CVE-2012-6121: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Cross-site scripting (XSS) vulnerability in Roundcube Webmail before 0.8.5 allows remote attackers to inject arbitrary web script or HTML via a (1) data:text or (2) vbscript link.
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.
Published: 2013-02-24T21:55Z
Repository: https://github.com/roundcube/roundcubemail
Language: PHP
Files changed: CHANGELOG, program/lib/washtml.php, tests/MailFunc.php
Commit date: 2012-12-04 09:17:08 +0100
Commit message: - Fix XSS vulnerability in vbscript: and data:text links handling (#1488850)

Diff: diff --git a/CHANGELOG b/CHANGELOG
index a47c95dcf..af7d29c04 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,8 +1,9 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Fix XSS vulnerability in vbscript: and data:text links handling (#1488850)
 - Fix broken message/part bodies when FETCH response contains more untagged lines (#1488836)
 - Fix empty email on identities list after identity update (#1488834)
 - Add new identities_level: (4) one identity with possibility to edit only signature
 - Use Delivered-To header as a last resort for identity selection (#1488840)
 - Fix XSS vulnerability using Flash files (#1488828)
diff --git a/program/lib/washtml.php b/program/lib/washtml.php
index 0d4ffdb4b..d13d66404 100644
--- a/program/lib/washtml.php
+++ b/program/lib/washtml.php
@@ -212,11 +212,11 @@ class washtml
 
     foreach ($node->attributes as $key => $plop) {
       $key = strtolower($key);
       $value = $node->getAttribute($key);
       if (isset($this->_html_attribs[$key]) ||
-         ($key == 'href' && !preg_match('!^javascript!i', $value)
+         ($key == 'href' && !preg_match('!^(javascript|vbscript|data:text)!i', $value)
            && preg_match('!^([a-z][a-z0-9.+-]+:|//|#).+!i', $value))
       ) {
         $t .= ' ' . $key . '="' . htmlspecialchars($value, ENT_QUOTES) . '"';
       }
       else if ($key == 'style' && ($style = $this->wash_style($value))) {
diff --git a/tests/MailFunc.php b/tests/MailFunc.php
index 967277c2a..4d4250c22 100644
--- a/tests/MailFunc.php
+++ b/tests/MailFunc.php
@@ -94,10 +94,24 @@ class MailFunc extends PHPUnit_Framework_TestCase
 
         $this->assertNotRegExp('/alert|expression|javascript|xss/', $washed, "Remove evil style blocks");
         $this->assertNotRegExp('/font-style:italic/', $washed, "Allow valid styles");
     }
 
+    /**
+     * Test the elimination of some XSS vulnerabilities
+     */
+    function test_html_xss3()
+    {
+        // #1488850
+        $html = '<p><a href="data:text/html,&lt;script&gt;alert(document.cookie)&lt;/script&gt;">Firefox</a>'
+            .'<a href="vbscript:alert(document.cookie)">Internet Explorer</a></p>';
+        $washed = rcmail_wash_html($html, array('safe' => true), array());
+
+        $this->assertNotRegExp('/data:text/', $washed, "Remove data:text/html links");
+        $this->assertNotRegExp('/vbscript:/', $washed, "Remove vbscript: links");
+    }
+
     /**
      * Test washtml class on non-unicode characters (#1487813)
      */
     function test_washtml_utf8()
     {

Vulnerable code:          ($key == 'href' && !preg_match('!^javascript!i', $value)
Fixed code: - Fix XSS vulnerability in vbscript: and data:text links handling (#1488850)
         ($key == 'href' && !preg_match('!^(javascript|vbscript|data:text)!i', $value)
    /**
     * Test the elimination of some XSS vulnerabilities
     */
    function test_html_xss3()
    {
        // #1488850
        $html = '<p><a href="data:text/html,&lt;script&gt;alert(document.cookie)&lt;/script&gt;">Firefox</a>'
            .'<a href="vbscript:alert(document.cookie)">Internet Explorer</a></p>';
        $washed = rcmail_wash_html($html, array('safe' => true), array());

        $this->assertNotRegExp('/data:text/', $washed, "Remove data:text/html links");
        $this->assertNotRegExp('/vbscript:/', $washed, "Remove vbscript: links");
    }