Executive brief
Unhead is a library used to manage HTML head tags in server-side rendered web applications. The useHeadSafe function, which is recommended by Nuxt documentation for safely handling user-generated metadata, can be bypassed to inject arbitrary HTML event handlers (such as onload) into rendered pages. An attacker who controls SEO metadata or user profile fields could inject malicious code that executes when a page is loaded, potentially stealing session credentials or performing actions on behalf of users.
Technical details
The vulnerability is a Cross-Site Scripting (XSS) flaw in the acceptDataAttrs function (CWE-79), which validates data-* attribute names but only checks the prefix, not whether the key contains spaces or other invalid HTML attribute characters. When attribute keys containing spaces and event handlers (e.g., "data-x onload=alert(1) y") are passed to useHeadSafe, they are interpolated directly into HTML without sanitization, allowing the injected event handler to be parsed as a separate HTML attribute. The attack is reliable when injected into link tags with rel="stylesheet" because the onload event fires once the stylesheet loads. No authentication is required; the attack is network-reachable and depends on user interaction (page load). The vulnerability was patched in version 2.1.11 with a regex validation to ensure attribute names contain only legal HTML attribute characters.
Affected products
- unjs Unhead <= 2.1.10
Timeline
- 2026-03-12: disclosed
- 2026-03-12: patched: Version 2.1.11 released with regex validation fix