Unhead Vulnerable to Bypass of URI Scheme Sanitization in makeTagSafe via Case-SensitivityGHSA-5339-hvwr-7582
NONEGHSA-5339-hvwr-7582 is a none-severity (CVSS 0) Cross-site Scripting (XSS) vulnerability in unhead. A fix is available for unhead — see the affected versions and patch details below.
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
Exploitation and automatability from CISA’s SSVC triage for GHSA-5339-hvwr-7582.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
Where this sits among everything scored
Real-World Exposure
How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.
unheadnpmDescription
The link.href check in makeTagSafe (safe.ts, line 68-71) uses String.includes(), which is case-sensitive:
if (key === 'href') {
if (val.includes('javascript:') || val.includes('data:')) {
return
}
next[key] = val
}
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.
PoC
useHeadSafe({
link: [{
rel: 'stylesheet',
href: 'DATA:text/css,body{display:none}'
}]
})
SSR output:
<link rel="stylesheet" href="DATA:text/css,body{display:none}">
The 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.
Any case variation works: DATA:, Data:, dAtA:, JAVASCRIPT:, etc.
Suggested fix
if (key === 'href') {
const lower = val.toLowerCase()
if (lower.includes('javascript:') || lower.includes('data:')) {
return
}
next[key] = val
}
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | unhead | all versions | 2.1.11npm install unhead@2.1.11 |
Affected Products
unheadunjsDetection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for unhead, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update unhead to 2.1.11 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-5339-hvwr-7582 is resolved across your whole dependency graph.
Workarounds
Escape or sanitise the affected output on the server side rather than relying on client-side filtering, and add a Content-Security-Policy that blocks inline script execution so injected markup cannot run even if it reaches the page.
Frequently Asked Questions
Is GHSA-5339-hvwr-7582 in your dependencies?
Find it across npm, including transitive dependencies.