CVE-2020-12625: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: An issue was discovered in Roundcube Webmail before 1.4.4. There is a cross-site scripting (XSS) vulnerability in rcube_washtml.php because JavaScript code can occur in the CDATA of an HTML message.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 6.1
Published: 2020-05-04T02:15Z
Repository: https://github.com/roundcube/roundcubemail
Language: PHP
Files changed: CHANGELOG, program/lib/Roundcube/rcube_washtml.php, tests/Framework/Washtml.php
Commit date: 2020-04-26 07:59:47 +0200
Commit message: Fix XSS issue in handling of CDATA in HTML messages

Diff: diff --git a/CHANGELOG b/CHANGELOG
index 3f1242d831..33ca74f19d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -39,10 +39,11 @@ CHANGELOG Roundcube Webmail
 - Fix characters encoding in group rename input after group creation/rename (#7330)
 - Fix bug where some message/rfc822 parts could not be attached on forward (#7323)
 - Make install-jsdeps.sh script working without the 'file' program installed (#7325)
 - Fix performance issue of parsing big HTML messages by disabling HTML5 parser for these (#7331)
 - Fix so Print button for PDF attachments works on Firefox >= 75 (#5125)
+- Security: Fix XSS issue in handling of CDATA in HTML messages
 
 RELEASE 1.4.3
 -------------
 - Enigma: Fix so key list selection is reset when opening key creation form (#7154)
 - Enigma: Fix so using list checkbox selection does not load the key preview frame
diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php
index cb1c5b1d1f..f2200e5385 100644
--- a/program/lib/Roundcube/rcube_washtml.php
+++ b/program/lib/Roundcube/rcube_washtml.php
@@ -546,13 +546,10 @@ class rcube_washtml
                     $dump .= $this->dumpHtml($node, $level); // ignore tags not its content
                 }
                 break;
 
             case XML_CDATA_SECTION_NODE:
-                $dump .= $node->nodeValue;
-                break;
-
             case XML_TEXT_NODE:
                 $dump .= htmlspecialchars($node->nodeValue, ENT_COMPAT | ENT_HTML401 | ENT_SUBSTITUTE, $this->config['charset']);
                 break;
 
             case XML_HTML_DOCUMENT_NODE:
diff --git a/tests/Framework/Washtml.php b/tests/Framework/Washtml.php
index 84c9af6465..d66a3dd1fe 100644
--- a/tests/Framework/Washtml.php
+++ b/tests/Framework/Washtml.php
@@ -504,6 +504,19 @@ class Framework_Washtml extends PHPUnit\Framework\TestCase
         $html   = 'First line<br /><html>Second line';
         $washed = $washer->wash($html);
 
         $this->assertContains('First line', $washed);
     }
+
+    /**
+     * Test CDATA cleanup
+     */
+    function test_cdata()
+    {
+        $html = '<p><![CDATA[<script>alert(document.cookie)</script>]]></p>';
+
+        $washer = new rcube_washtml;
+        $washed = $washer->wash($html);
+
+        $this->assertTrue(strpos($washed, '<script>') === false, "CDATA content");
+    }
 }

Vulnerable code:                 $dump .= $node->nodeValue;
                break;

Fixed code: - Security: Fix XSS issue in handling of CDATA in HTML messages

    /**
     * Test CDATA cleanup
     */
    function test_cdata()
    {
        $html = '<p><![CDATA[<script>alert(document.cookie)</script>]]></p>';

        $washer = new rcube_washtml;
        $washed = $washer->wash($html);

        $this->assertTrue(strpos($washed, '<script>') === false, "CDATA content");
    }