VYPR
Moderate severityNVD Advisory· Published Apr 10, 2025· Updated Apr 10, 2025

Silverstripe Framework has a XSS vulnerability in HTML editor

CVE-2025-30148

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].

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.

PackageAffected versionsPatched versions
silverstripe/frameworkPackagist
< 5.3.235.3.23

Affected products

3

Patches

1
e99cfd62d160

[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

News mentions

0

No linked articles in our index yet.