Silverstripe Framework has a XSS vulnerability in HTML editor
Description
Silverstripe Framework is a PHP framework which powers the Silverstripe CMS. Prior to 5.3.23, bad actor with access to edit content in the CMS could send a specifically crafted encoded payload to the server, which could be used to inject a JavaScript payload on the front end of the site. The payload would be sanitized on the client-side, but server-side sanitization doesn't catch it. The server-side sanitization logic has been updated to sanitize against this attack. This vulnerability is fixed in 5.3.23.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Silverstripe CMS prior to 5.3.23 allows stored XSS via crafted payloads containing the backspace character that bypass server-side sanitization.
Vulnerability
Overview
CVE-2025-30147 is a stored Cross-Site Scripting (XSS) vulnerability in the Silverstripe Framework, which powers Silverstripe CMS. Prior to version 5.3.23, the server-side sanitization logic did not properly handle the backspace character (ASCII 0x08). An attacker with content editing privileges could craft a payload that includes a backspace character within an HTML attribute—such as a href or src—to bypass sanitization filters that only catch client-side patterns. The client-side sanitization would remove the dangerous payload, but the server would store the unsanitized version, leading to persistent XSS on the front end [1][2][3].
Exploitation
To exploit this vulnerability, an attacker must have an account with permission to edit content in the CMS. They can then submit a specially encoded payload, for example embedding a backspace character before javascript:alert('XSS') inside a link or image tag. The server-side sanitizer did not strip the backspace character, allowing the malicious JavaScript to be stored and later executed in the browser of any user viewing the affected page. The proof-of-concept test cases in the fix commit show how payloads like `` would bypass sanitization [3].
Impact
Successful exploitation allows an authenticated attacker to inject arbitrary JavaScript into the front-end pages of the site. This can lead to session hijacking, credential theft, defacement, or redirection to malicious sites. The scope is limited to users who have CMS edit rights, but the impact on visitors is severe because the injected script runs in their browsers without requiring any further authentication [1][2].
Mitigation
The vulnerability is fixed in Silverstripe Framework version 5.3.23. Administrators should upgrade immediately. No workarounds are documented; the fix updates the server-side sanitization to remove backspace characters before storing content [2][4].
- NVD - CVE-2025-30148
- [CVE-2025-30148] Handle backspace characters in XSS by emteknetnz · Pull Request #11682 · silverstripe/silverstripe-framework
- [CVE-2025-30148] Handle backspace characters in XSS · silverstripe/silverstripe-framework@e99cfd6
- security-advisories/silverstripe/framework/CVE-2025-30148.yaml at master · FriendsOfPHP/security-advisories
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
silverstripe/frameworkPackagist | < 5.3.23 | 5.3.23 |
Affected products
3- Range: <5.3.23
- silverstripe/silverstripe-frameworkv5Range: < 5.3.23
Patches
1e99cfd62d160[CVE-2025-30148] Handle backspace characters in XSS
3 files changed · +48 −1
src/Core/XssSanitiser.php+3 −1 modified@@ -201,7 +201,9 @@ private function getStripAttributeContentsRegex(): string $this->splitWithWhitespaceRegex('vbscript:'), ]; // Regex is "starts with any of these, with optional whitespace at the start, case insensitive" - return '#^\s*(' . implode('|', $regexes) . ')#iu'; + // \x08 is the backspace character, though it only causes vulnerabilities if it's at the start + // or end of a string + return '#^(\s|\x08)*(' . implode('|', $regexes) . ')(\s|\x08)*#iu'; } private function splitWithWhitespaceRegex(string $string): string
tests/php/Core/XssSanitiserTest.php+19 −0 modified@@ -9,6 +9,9 @@ class XssSanitiserTest extends SapphireTest { + // This is the backspace character. It needs to be escaped in double-quotes. + private const CHAR_BACKSPACE = "\x08"; + protected $usesDatabase = false; public function provideSanitise(): array @@ -73,6 +76,14 @@ public function provideSanitise(): array 'input' => '<a href="javascript:alert(\'ok\')">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</a>', 'expected' => '<a>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</a>', ], + [ + 'input' => '<a href="' . XssSanitiserTest::CHAR_BACKSPACE . 'javascript:alert(\'ok\')">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</a>', + 'expected' => '<a>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</a>', + ], + [ + 'input' => '<a href="javascript:alert(\'ok\')' . XssSanitiserTest::CHAR_BACKSPACE . '">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</a>', + 'expected' => '<a>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</a>', + ], [ // Not exploitable XSS 'input' => '<<a href="javascript:evil"/>a href="javascript:evil"/>', @@ -132,6 +143,10 @@ public function provideSanitise(): array 'input' => '<IMG SRC="javascript:alert(\'XSS\');">', 'expected' => '<img>', ], + [ + 'input' => '<IMG SRC="' . XssSanitiserTest::CHAR_BACKSPACE . 'javascript:alert(\'XSS\');">', + 'expected' => '<img>', + ], [ 'input' => '<IMG SRC=javascript:alert(\'XSS\')>', 'expected' => '<img>', @@ -206,6 +221,10 @@ public function provideSanitise(): array 'input' => '<BGSOUND SRC="javascript:alert(\'XSS\');">', 'expected' => '<bgsound></bgsound>', ], + [ + 'input' => '<BGSOUND SRC="' . XssSanitiserTest::CHAR_BACKSPACE . 'javascript:alert(\'XSS\');">', + 'expected' => '<bgsound></bgsound>', + ], [ // Not exploitable XSS 'input' => '<BR SIZE="&{alert(\'XSS\')}">',
tests/php/Forms/HTMLEditor/HTMLEditorSanitiserTest.php+26 −0 modified@@ -10,6 +10,8 @@ class HTMLEditorSanitiserTest extends FunctionalTest { + // This is the backspace character. It needs to be escaped in double-quotes. + private const CHAR_BACKSPACE = "\x08"; public function provideSanitise(): array { @@ -80,6 +82,18 @@ public function provideSanitise(): array '<a>Test</a>', 'Javascript in the href attribute of a link is completely removed' ], + [ + 'a[href|target|rel]', + '<a href="' . HTMLEditorSanitiserTest::CHAR_BACKSPACE . 'javascript:alert(0);">Test</a>', + '<a>Test</a>', + 'Javascript in the href attribute with leading backspace of a link is completely removed' + ], + [ + 'a[href|target|rel]', + '<a href="javascript:alert(0);' . HTMLEditorSanitiserTest::CHAR_BACKSPACE . '">Test</a>', + '<a>Test</a>', + 'Javascript in the href attribute with backspace in middle of a link is completely removed' + ], [ 'a[href|target|rel]', '<a href="' . implode("\n", str_split(' javascript:')) . '">Test</a>', @@ -110,6 +124,12 @@ public function provideSanitise(): array '<iframe></iframe>', 'Javascript with tab elements the src attribute of an iframe is completely removed' ], + [ + 'iframe[src]', + '<iframe src="' . HTMLEditorSanitiserTest::CHAR_BACKSPACE . 'javascript:alert(0);"></iframe>', + '<iframe></iframe>', + 'Javascript in the src attribute of an iframe with a backspace is completely removed' + ], [ 'object[data]', '<object data="OK"></object>', @@ -128,6 +148,12 @@ public function provideSanitise(): array '<object></object>', 'Object with dangerous javascript content in data attribute with quotes is completely removed' ], + [ + 'object[data]', + '<object data="' . HTMLEditorSanitiserTest::CHAR_BACKSPACE . 'javascript:alert()">', + '<object></object>', + 'Object with dangerous javascript content in data attribute with backspace is completely removed' + ], [ 'object[data]', '<object data="data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5sb2NhdGlvbik8L3NjcmlwdD4=">',
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-rhx4-hvx9-j387ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-30148ghsaADVISORY
- github.com/FriendsOfPHP/security-advisories/blob/master/silverstripe/framework/CVE-2025-30148.yamlghsaWEB
- github.com/silverstripe/silverstripe-framework/commit/e99cfd62d160d145a76fcf9631e6b11226e42358ghsax_refsource_MISCWEB
- github.com/silverstripe/silverstripe-framework/pull/11682ghsaWEB
- github.com/silverstripe/silverstripe-framework/security/advisories/GHSA-rhx4-hvx9-j387ghsax_refsource_CONFIRMWEB
- www.silverstripe.org/download/security-releases/cve-2025-30148ghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.