Unhead Leading-Zero HTML Entity Padding Vulnerability Allowing Protocol Injection
Vulnerability
A vulnerability in Unhead, a document head and template manager, prior to version 2.1.13, allows for the injection of dangerous URI protocols into server-side rendered HTML. This issue arises in the 'useHeadSafe()' composable, which is recommended by Nuxt for safely rendering user-supplied content in the document head. The vulnerability is caused by the 'hasDangerousProtocol()' function, which decodes HTML entities before checking for blocked URI schemes such as 'javascript:', 'data:', and 'vbscript:'. The decoding process uses regular expressions that improperly limit the number of digits, allowing padded entities to bypass the scheme checks and be executed in the browser.
Impact
Exploitation of this vulnerability leads to the injection of 'javascript:' and 'data:' URIs into server-rendered HTML, where they can be executed in the browser. This behavior violates the security guarantees provided by the 'useHeadSafe()' composable, which is intended to protect against such injections.
Reproduction
To reproduce this vulnerability, create a Nuxt 4 project and install Unhead version 2.1.12. Replace the default 'pages/index.vue' file with a version that uses 'useHeadSafe()' to inject a 'data:' URI or a 'javascript:' URI padded with leading zeros. When the page is rendered, the padded entity will bypass the scheme checks and execute in the browser.
Remediation
Users can update to Unhead version 2.1.13, which removes the fixed digit caps from the regular expressions that decode HTML entities, allowing for proper validation of leading-zero padded entities before scheme checks are applied.
Vulnerability Rating
Our algorithm analyzes dozens of metrics to generate these 8 key vulnerability categories, which are then combined to calculate the overall risk score.
