CVE-2024-32981: Insufficient Information (NVD-CWE-noinfo)
value: Silverstripe framework is the PHP framework forming the base for the Silverstripe CMS. In affected versions a bad actor with access to edit content in the CMS could add 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 sanitised on the client-side, but server-side sanitisation doesn't catch it. The server-side sanitisation logic has been updated to sanitise against this type of attack in version 5.2.16. All users are advised to upgrade. There are no known workarounds for this vulnerability.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-07-17T20:15Z
Repository: https://github.com/silverstripe/silverstripe-framework
Language: PHP
Files changed: src/Forms/HTMLEditor/HTMLEditorSanitiser.php, tests/php/Forms/HTMLEditor/HTMLEditorSanitiserTest.php
Commit date: 2024-07-17 11:04:27 +1200
Commit message: [CVE-2024-32981] Disallow `data:text/html` in data attributes

Diff: diff --git a/src/Forms/HTMLEditor/HTMLEditorSanitiser.php b/src/Forms/HTMLEditor/HTMLEditorSanitiser.php
index a075d98fa9..a979d1c2fe 100644
--- a/src/Forms/HTMLEditor/HTMLEditorSanitiser.php
+++ b/src/Forms/HTMLEditor/HTMLEditorSanitiser.php
@@ -345,11 +345,11 @@ class HTMLEditorSanitiser
                 foreach ($elementRule->attributesForced as $attr => $forced) {
                     $el->setAttribute($attr, $forced);
                 }
 
                 // Matches "javascript:" with any arbitrary linebreaks inbetween the characters.
-                $regex = '/^\s*' . implode('\s*', str_split('javascript:')) . '/i';
+                $regex = '#^\s*(' . implode('\s*', str_split('javascript:')) . '|' . implode('\s*', str_split('data:text/html;')) . ')#i';
                 // Strip out javascript execution in href or src attributes.
                 foreach (['src', 'href', 'data'] as $dangerAttribute) {
                     if ($el->hasAttribute($dangerAttribute)) {
                         if (preg_match($regex, $el->getAttribute($dangerAttribute))) {
                             $el->removeAttribute($dangerAttribute);
diff --git a/tests/php/Forms/HTMLEditor/HTMLEditorSanitiserTest.php b/tests/php/Forms/HTMLEditor/HTMLEditorSanitiserTest.php
index 3d5c3d5c68..ac7272dc2c 100644
--- a/tests/php/Forms/HTMLEditor/HTMLEditorSanitiserTest.php
+++ b/tests/php/Forms/HTMLEditor/HTMLEditorSanitiserTest.php
@@ -118,11 +118,35 @@ class HTMLEditorSanitiserTest extends FunctionalTest
             ],
             [
                 'object[data]',
                 '<object data=javascript:alert()>',
                 '<object></object>',
-                'Object with dangerous content in data attribute is completely removed'
+                'Object with dangerous javascript content in data attribute is completely removed'
+            ],
+            [
+                'object[data]',
+                '<object data="javascript:alert()">',
+                '<object></object>',
+                'Object with dangerous javascript content in data attribute with quotes is completely removed'
+            ],
+            [
+                'object[data]',
+                '<object data="data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5sb2NhdGlvbik8L3NjcmlwdD4=">',
+                '<object></object>',
+                'Object with dangerous html content in data attribute is completely removed'
+            ],
+            [
+                'object[data]',
+                '<object data="' . implode("\n", str_split(' DATA:TEXT/HTML;')) . 'base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5sb2NhdGlvbik8L3NjcmlwdD4=">',
+                '<object></object>',
+                'Object with split upper-case dangerous html content in data attribute is completely removed'
+            ],
+            [
+                'object[data]',
+                '<object data="data:text/xml;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5sb2NhdGlvbik8L3NjcmlwdD4=">',
+                '<object data="data:text/xml;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5sb2NhdGlvbik8L3NjcmlwdD4="></object>',
+                'Object with safe xml content in data attribute is retained'
             ],
             [
                 'img[src]',
                 '<img src="https://owasp.org/myimage.jpg" style="url:xss" onerror="alert(1)">',
                 '<img src="https://owasp.org/myimage.jpg">',

Vulnerable code:                 $regex = '/^\s*' . implode('\s*', str_split('javascript:')) . '/i';
                'Object with dangerous content in data attribute is completely removed'
Fixed code:                 $regex = '#^\s*(' . implode('\s*', str_split('javascript:')) . '|' . implode('\s*', str_split('data:text/html;')) . ')#i';
                'Object with dangerous javascript content in data attribute is completely removed'
            ],
            [
                'object[data]',
                '<object data="javascript:alert()">',
                '<object></object>',
                'Object with dangerous javascript content in data attribute with quotes is completely removed'
            ],
            [
                'object[data]',
                '<object data="data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5sb2NhdGlvbik8L3NjcmlwdD4=">',
                '<object></object>',
                'Object with dangerous html content in data attribute is completely removed'
            ],
            [
                'object[data]',
                '<object data="' . implode("\n", str_split(' DATA:TEXT/HTML;')) . 'base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5sb2NhdGlvbik8L3NjcmlwdD4=">',
                '<object></object>',
                'Object with split upper-case dangerous html content in data attribute is completely removed'
            ],
            [
                'object[data]',
                '<object data="data:text/xml;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5sb2NhdGlvbik8L3NjcmlwdD4=">',
                '<object data="data:text/xml;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5sb2NhdGlvbik8L3NjcmlwdD4="></object>',
                'Object with safe xml content in data attribute is retained'