Silverstripe is a well-known open-source framework popular for building complex content management systems in PHP. In July 2022, a critical security vulnerability – CVE-2022-37429 – was disclosed in the Silverstripe framework versions through 4.11. This bug allows attackers to execute cross-site scripting (XSS) through a tricky manipulation of the href attribute on link (<a>) tags when javascript URLs are split using whitespace.
In this article, we’ll break down CVE-2022-37429, show you exactly how it can be exploited, why it works, and what to do about it. You’ll see both code examples and references to further reading.
What’s the Vulnerability?
Silverstripe’s output escaping wasn’t robust enough to handle href attributes split by whitespace in a javascript: URL. An attacker could sneak JavaScript code into a link that might otherwise be filtered and thus trick users into running malicious scripts — a classic case of XSS.
This was first found and reported at Huntr.dev and has since been acknowledged and patched in later versions.
How Does the Attack Work?
Most XSS filters simply check if the href starts with javascript: and block it. However, JavaScript engines will ignore variations in whitespace, which means the below value will still execute JavaScript:
<a href="javascript :alert(1)">Click me!</a>
Silverstripe’s sanitization missed these cases – if a payload included whitespace(s) inside the href, scripts could sneak through and execute!
Suppose you have a Silverstripe template where user input is reflected into a link
<!-- Silverstripe template code (unsafe!) -->
<a href="$UserSuppliedValue">Profile</a>
If an attacker submits this as input
javascript :alert(1)
This results in HTML like
<a href="javascript :alert(1)">Profile</a>
If a user clicks this link, alert(1) pops up. In a real-world scenario, attackers can inject more harmful code than alert(1) – think stealing cookies, session tokens, or spreading malware.
Proof-of-Concept (PoC)
Simple PoC for testing:
Paste this into any Silverstripe CMS field or area that outputs to an href
javascript :alert(document.domain)
Once the link renders on the page, clicking it should trigger an alert box, as shown in this quick demo:
<!-- Malicious link via input injection -->
<a href="javascript : alert(document.domain)">Click here!</a>
Notice: Even though there are multiple spaces (or even tabs/newlines) between javascript and :, the browser still executes the code.
Traditional XSS protections often have patterns like
if (stripos($href, 'javascript:') === ) {
// Block or sanitize
}
But with whitespace
"javascript :alert(1)"
stripos($href, 'javascript:') returns false
So the check is bypassed.
Fixes & Mitigation
Silverstripe 4.11 and earlier are affected.
The fix (as of pull request #10465) is to normalize whitespace and more strictly check for javascript: (ignoring spaces, tabs, etc.).
A quick way to filter hrefs in PHP could be
function safeHref($input) {
// Remove all whitespace (space, tabs, newlines) before first ':'
$clean = preg_replace('/\s+:/', ':', $input);
// Block if it begins with javascript:
if (stripos($clean, 'javascript:') === ) {
return '#';
}
return htmlspecialchars($input, ENT_QUOTES);
}
Resources & References
- Original Advisory: GitHub Security Advisory – GHSA-8w95-qvp5-qwh2
- NVD Entry for CVE-2022-37429: https://nvd.nist.gov/vuln/detail/CVE-2022-37429
- Huntr Report: https://huntr.dev/bounties/89ebd6be-552f-4bd-831e-af841ac01577/
- Silverstripe Patch Pull Request: https://github.com/silverstripe/silverstripe-framework/pull/10465
Final Thoughts
CVE-2022-37429 is a prime example of how attackers can get around naive input filtering with creative use of whitespace. Always validate and sanitize user input, and keep your frameworks up to date!
If you’re running Silverstripe 4.11 or earlier, update now to stay safe from XSS attacks like this one.
Timeline
Published on: 11/23/2022 02:15:00 UTC
Last modified on: 11/28/2022 15:31:00 UTC