{"id":"CVE-2026-31873","aliases":["CLSA-2026-1788988912","CLSA-2026-1792161471","CLSA-2026-1792161537","CLSA-2026-1792161579","CLSA-2026-1792161644","CLSA-2026-1792162014","EUVD-2026-11640","GHSA-5339-hvwr-7582"],"status":"published","title":"Unhead has a Bypass of URI Scheme Sanitization in makeTagSafe via Case-Sensitivity","description":"Unhead is a document head and template manager. Prior to 2.1.11, The link.href check in makeTagSafe (safe.ts) uses String.includes(), which is case-sensitive. Browsers treat URI schemes case-insensitively. DATA:text/css,... is the same as data:text/css,... to the browser, but 'DATA:...'.includes('data:') returns false. An attacker can inject arbitrary CSS for UI redressing or data exfiltration via CSS attribute selectors with background-image callbacks. This vulnerability is fixed in 2.1.11.","severity":{"version":"3.1","score":0,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N","level":"none","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-12","score":0.00268,"percentile":0.19128,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-79"],"published":"2026-03-12T14:19:25Z","modified":"2026-10-28T02:30:52Z","fixes":[{"ecosystem":"npm","package":"unhead","fixed_in":["2.1.11"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"unhead","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"2.1.10"},{"fixed":"2.1.11"}]}]},{"source":"osv","ecosystem":"TuxCare:npm","package":"unhead","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.11.20-tuxcare.0"},{"fixed":"1.11.20-tuxcare.1"}]}],"versions":["1.11.20"],"bundled":2},{"source":"osv","ecosystem":"TuxCare:npm","package":"@unhead/dom","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.11.20-tuxcare.0"},{"fixed":"1.11.20-tuxcare.1"}]}],"versions":["1.11.20"],"bundled":2},{"source":"osv","ecosystem":"TuxCare:npm","package":"@unhead/shared","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.11.20-tuxcare.0"},{"fixed":"1.11.20-tuxcare.1"}]}],"versions":["1.11.20"],"bundled":2},{"source":"osv","ecosystem":"TuxCare:npm","package":"@unhead/ssr","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.11.20-tuxcare.0"},{"fixed":"1.11.20-tuxcare.1"}]}],"versions":["1.11.20"],"bundled":2},{"source":"osv","ecosystem":"TuxCare:npm","package":"@unhead/vue","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.11.20-tuxcare.0"},{"fixed":"1.11.20-tuxcare.1"}]}],"versions":["1.11.20"],"bundled":2},{"source":"osv","ecosystem":"TuxCare:npm","package":"@unhead/schema","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"1.11.20-tuxcare.0"},{"fixed":"1.11.20-tuxcare.1"}]}],"versions":["1.11.20"],"bundled":2},{"source":"osv","ecosystem":"npm","package":"unhead","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"2.1.11"}]}]}],"products":[{"vendor":"unjs","product":"unhead"}],"references":[{"url":"https://github.com/unjs/unhead/security/advisories/GHSA-5339-hvwr-7582","tags":["x_refsource_CONFIRM","Exploit","Mitigation","Vendor Advisory","advisory","web"]},{"url":"https://github.com/unjs/unhead/releases/tag/v2.1.11","tags":["web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-31873","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-5339-hvwr-7582"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/31xxx/CVE-2026-31873.json","tags":["advisory"]},{"url":"https://github.com/unjs/unhead","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-31873","title":"Unhead has a Bypass of URI Scheme Sanitization in makeTagSafe via Case-Sensitivity","description":"Unhead is a document head and template manager. Prior to 2.1.11, The link.href check in makeTagSafe (safe.ts) uses String.includes(), which is case-sensitive. Browsers treat URI schemes case-insensitively. DATA:text/css,... is the same as data:text/css,... to the browser, but 'DATA:...'.includes('data:') returns false. An attacker can inject arbitrary CSS for UI redressing or data exfiltration via CSS attribute selectors with background-image callbacks. This vulnerability is fixed in 2.1.11.","status":"published","published":"2026-03-12T17:20:35.66Z","modified":"2026-03-12T17:46:46.723Z","cvss":[{"version":"3.1","score":0,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N","level":"none","assessor":"cna"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:19:51.277563Z"}],"euvd":[{"id":"EUVD-2026-11640","description":"Unhead is a document head and template manager. Prior to 2.1.11, The link.href check in makeTagSafe (safe.ts) uses String.includes(), which is case-sensitive. Browsers treat URI schemes case-insensitively. DATA:text/css,... is the same as data:text/css,... to the browser, but 'DATA:...'.includes('data:') returns false. An attacker can inject arbitrary CSS for UI redressing or data exfiltration via CSS attribute selectors with background-image callbacks. This vulnerability is fixed in 2.1.11.","status":"published","published":"2026-03-12T17:20:35Z","modified":"2026-03-12T17:46:46Z","updated_at":"2026-11-02T19:25:35.78849Z"}],"ghsa":[{"id":"GHSA-5339-hvwr-7582","title":"Unhead Vulnerable to Bypass of URI Scheme Sanitization in makeTagSafe via Case-Sensitivity","description":"The `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\u003clink rel=\"stylesheet\" href=\"DATA:text/css,body{display:none}\"\u003e\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```","status":"published","published":"2026-03-12T14:19:25Z","modified":"2026-03-12T19:14:32Z","cvss":[{"version":"3.1","score":0,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N","level":"none"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:39:35.644357Z"}],"nvd":[{"id":"CVE-2026-31873","description":"Unhead is a document head and template manager. Prior to 2.1.11, The link.href check in makeTagSafe (safe.ts) uses String.includes(), which is case-sensitive. Browsers treat URI schemes case-insensitively. DATA:text/css,... is the same as data:text/css,... to the browser, but 'DATA:...'.includes('data:') returns false. An attacker can inject arbitrary CSS for UI redressing or data exfiltration via CSS attribute selectors with background-image callbacks. This vulnerability is fixed in 2.1.11.","status":"published","published":"2026-03-12T18:16:24.387Z","modified":"2026-06-17T10:34:40.49Z","cvss":[{"version":"3.1","score":0,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N","level":"none","assessor":"secondary"},{"version":"3.1","score":6.1,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"primary"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:12:09.358914Z"}],"osv":[{"id":"CVE-2026-31873","title":"Unhead has a Bypass of URI Scheme Sanitization in makeTagSafe via Case-Sensitivity","description":"Unhead is a document head and template manager. Prior to 2.1.11, The link.href check in makeTagSafe (safe.ts) uses String.includes(), which is case-sensitive. Browsers treat URI schemes case-insensitively. DATA:text/css,... is the same as data:text/css,... to the browser, but 'DATA:...'.includes('data:') returns false. An attacker can inject arbitrary CSS for UI redressing or data exfiltration via CSS attribute selectors with background-image callbacks. This vulnerability is fixed in 2.1.11.","status":"published","published":"2026-03-12T17:20:35.66Z","modified":"2026-10-28T02:30:52.294266782Z","cvss":[{"version":"3.1","score":0,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N","level":"none"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T15:45:01.218144Z"},{"id":"GHSA-5339-hvwr-7582","title":"Unhead Vulnerable to Bypass of URI Scheme Sanitization in makeTagSafe via Case-Sensitivity","description":"The `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\u003clink rel=\"stylesheet\" href=\"DATA:text/css,body{display:none}\"\u003e\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```","status":"published","published":"2026-03-12T14:19:25Z","modified":"2026-03-14T06:26:21.006093Z","cvss":[{"version":"3.1","score":0,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:N","level":"none"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T15:46:37.864461Z"},{"id":"CLSA-2026-1788988912","title":"TuxCare security update for unhead (2 CVEs)","description":"TuxCare rebuilt unhead to address 2 CVEs. Fixed in 1.11.20-tuxcare.1.","status":"published","published":"2026-09-09T21:21:52Z","modified":"2026-10-15T09:47:55.755054109Z","updated_at":"2026-11-02T15:43:47.938828Z"},{"id":"CLSA-2026-1792161471","title":"TuxCare security update for @unhead/dom (2 CVEs)","description":"TuxCare rebuilt @unhead/dom to address 2 CVEs. Fixed in 1.11.20-tuxcare.1.","status":"published","published":"2026-10-16T14:37:51Z","modified":"2026-10-16T16:31:03.525728277Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161537","title":"TuxCare security update for @unhead/shared (2 CVEs)","description":"TuxCare rebuilt @unhead/shared to address 2 CVEs. Fixed in 1.11.20-tuxcare.1.","status":"published","published":"2026-10-16T14:38:57Z","modified":"2026-10-16T16:31:05.413526794Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161579","title":"TuxCare security update for @unhead/ssr (2 CVEs)","description":"TuxCare rebuilt @unhead/ssr to address 2 CVEs. Fixed in 1.11.20-tuxcare.1.","status":"published","published":"2026-10-16T14:39:39Z","modified":"2026-10-16T16:30:23.848714479Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792161644","title":"TuxCare security update for @unhead/vue (2 CVEs)","description":"TuxCare rebuilt @unhead/vue to address 2 CVEs. Fixed in 1.11.20-tuxcare.1.","status":"published","published":"2026-10-16T14:40:44Z","modified":"2026-10-16T16:31:06.614972478Z","updated_at":"2026-11-02T15:43:51.213191Z"},{"id":"CLSA-2026-1792162014","title":"TuxCare security update for @unhead/schema (2 CVEs)","description":"TuxCare rebuilt @unhead/schema to address 2 CVEs. Fixed in 1.11.20-tuxcare.1.","status":"published","published":"2026-10-16T14:46:54Z","modified":"2026-10-16T16:31:20.258162176Z","updated_at":"2026-11-02T15:43:51.466048Z"}]}}
