[Pkg-roundcube-maintainers] roundcube: CVE-2020-16145: XSS vulnerability via HTML messages with malicious SVG or math content

Guilhem Moulin guilhem at debian.org
Tue Aug 11 18:11:57 BST 2020


Dear security team,

In a recent post roundcube webmail upstream has announced the following
security fix for #968216:

    Cross-site scripting (XSS) via HTML messages with malicious SVG
    or math content (CVE-2020-16145)

AFAICT CVE-2020-16145 is only about SVG not math, but the upstream
commit addresses both so I opened a single bug:
https://github.com/roundcube/roundcubemail/commit/589d36010048300ed39f4887aab1afd3ae98d00e

Debdiff tested and attached, but I'd appreciate if you could take care
of the DLA :-)

Thanks!
Cheers,
-- 
Guilhem.
-------------- next part --------------
diffstat for roundcube-1.2.3+dfsg.1 roundcube-1.2.3+dfsg.1

 changelog                    |    8 +++
 patches/CVE-2020-16145.patch |  107 +++++++++++++++++++++++++++++++++++++++++++
 patches/series               |    1 
 3 files changed, 116 insertions(+)

diff -Nru roundcube-1.2.3+dfsg.1/debian/changelog roundcube-1.2.3+dfsg.1/debian/changelog
--- roundcube-1.2.3+dfsg.1/debian/changelog	2020-07-06 16:14:59.000000000 +0200
+++ roundcube-1.2.3+dfsg.1/debian/changelog	2020-08-11 18:38:40.000000000 +0200
@@ -1,3 +1,11 @@
+roundcube (1.2.3+dfsg.1-4+deb9u7) stretch-security; urgency=high
+
+  * Backport security fix for CVE-2020-16145: Cross-site scripting (XSS)
+    vulnerability via HTML messages with malicious svg or math
+    content. (Closes: #968216)
+
+ -- Guilhem Moulin <guilhem at debian.org>  Tue, 11 Aug 2020 18:38:40 +0200
+
 roundcube (1.2.3+dfsg.1-4+deb9u6) stretch; urgency=high
 
   * Backport security fix for CVE-2020-15562: Cross-Site Scripting (XSS)
diff -Nru roundcube-1.2.3+dfsg.1/debian/patches/CVE-2020-16145.patch roundcube-1.2.3+dfsg.1/debian/patches/CVE-2020-16145.patch
--- roundcube-1.2.3+dfsg.1/debian/patches/CVE-2020-16145.patch	1970-01-01 01:00:00.000000000 +0100
+++ roundcube-1.2.3+dfsg.1/debian/patches/CVE-2020-16145.patch	2020-08-11 18:38:40.000000000 +0200
@@ -0,0 +1,107 @@
+commit 589d36010048300ed39f4887aab1afd3ae98d00e
+Author: Aleksander Machniak <alec at alec.pl>
+Date:   Sun Aug 9 18:02:16 2020 +0200
+
+    Fix cross-site scripting (XSS) via HTML messages with malicious svg or math content
+
+diff --git a/program/lib/Roundcube/rcube_washtml.php b/program/lib/Roundcube/rcube_washtml.php
+index 4c5ca46a3..81a3edf1b 100644
+--- a/program/lib/Roundcube/rcube_washtml.php
++++ b/program/lib/Roundcube/rcube_washtml.php
+@@ -365,7 +365,30 @@ class rcube_washtml
+                 return $this->config['blocked_src'];
+             }
+         }
+-        else if (preg_match('/^data:image.+/i', $uri)) { // RFC2397
++        else if (preg_match('/^data:image\/([^,]+),(.+)$/i', $uri, $matches)) { // RFC2397
++            // svg images can be insecure, we'll sanitize them
++            if (stripos($matches[1], 'svg') !== false) {
++                $svg = $matches[2];
++
++                if (stripos($matches[1], ';base64') !== false) {
++                    $svg  = base64_decode($svg);
++                    $type = $matches[1];
++                }
++                else {
++                    $type = $matches[1] . ';base64';
++                }
++
++                $washer = new self($this->config);
++                $svg    = $washer->wash($svg);
++
++                // Invalid svg content
++                if (empty($svg)) {
++                    return null;
++                }
++
++                return 'data:image/' . $type . ',' . base64_encode($svg);
++            }
++
+             return $uri;
+         }
+     }
+@@ -375,7 +398,7 @@ class rcube_washtml
+      */
+     private function is_link_attribute($tag, $attr)
+     {
+-        return ($tag == 'a' || $tag == 'area') && $attr == 'href';
++        return $attr === 'href';
+     }
+ 
+     /**
+@@ -387,6 +410,7 @@ class rcube_washtml
+             || $attr == 'color-profile' // SVG
+             || ($attr == 'poster' && $tag == 'video')
+             || ($attr == 'src' && preg_match('/^(img|source)$/i', $tag))
++            || ($tag == 'use' && $attr == 'href') // SVG
+             || ($tag == 'image' && $attr == 'href'); // SVG
+     }
+ 
+@@ -399,6 +423,31 @@ class rcube_washtml
+             'marker-end', 'marker-mid', 'clip-path', 'mask', 'cursor'));
+     }
+ 
++    /**
++     * Check if a specified element has an attribute with specified value.
++     * Do it in case-insensitive manner.
++     *
++     * @param DOMElement $node       The element
++     * @param string     $attr_name  The attribute name
++     * @param string     $attr_value The attribute value to find
++     *
++     * @return bool True if the specified attribute exists and has the expected value
++     */
++    private static function attribute_value($node, $attr_name, $attr_value)
++    {
++        $attr_name = strtolower($attr_name);
++
++        foreach ($node->attributes as $name => $attr) {
++            if (strtolower($name) === $attr_name) {
++                if (strtolower($attr_value) === strtolower($attr->nodeValue)) {
++                    return true;
++                }
++            }
++        }
++
++        return false;
++    }
++
+     /**
+      * The main loop that recurse on a node tree.
+      * It output only allowed tags with allowed attributes and allowed inline styles
+@@ -433,6 +482,15 @@ class rcube_washtml
+             switch ($node->nodeType) {
+             case XML_ELEMENT_NODE: //Check element
+                 $tagName = strtolower($node->tagName);
++
++                if (in_array($tagName, array('animate', 'animatecolor', 'set', 'animatetransform'))
++                    && self::attribute_value($node, 'attributename', 'href')
++                ) {
++                    // Insecure svg tags
++                    $dump .= "<!-- $tagName blocked -->";
++                    break;
++                }
++
+                 if ($callback = $this->handlers[$tagName]) {
+                     $dump .= call_user_func($callback, $tagName,
+                         $this->wash_attribs($node), $this->dumpHtml($node, $level), $this);
diff -Nru roundcube-1.2.3+dfsg.1/debian/patches/series roundcube-1.2.3+dfsg.1/debian/patches/series
--- roundcube-1.2.3+dfsg.1/debian/patches/series	2020-07-06 16:14:59.000000000 +0200
+++ roundcube-1.2.3+dfsg.1/debian/patches/series	2020-08-11 18:38:40.000000000 +0200
@@ -21,3 +21,4 @@
 CVE-2020-13964.patch
 CVE-2020-13965.patch
 CVE-2020-15562.patch
+CVE-2020-16145.patch
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-roundcube-maintainers/attachments/20200811/51370c62/attachment.sig>


More information about the Pkg-roundcube-maintainers mailing list