Bug #8715: Handle multiple data declarations per tag.
authorMichael M Slusarz <slusarz@curecanti.org>
Tue, 4 May 2010 05:04:25 +0000 (23:04 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Tue, 4 May 2010 05:10:08 +0000 (23:10 -0600)
framework/Text_Filter/lib/Horde/Text/Filter/Xss.php
framework/Text_Filter/test/Horde/Text/Filter/fixtures/xss95.html [new file with mode: 0644]
framework/Text_Filter/test/Horde/Text/Filter/xss.phpt

index 9242ecf..7c71ad1 100644 (file)
@@ -214,15 +214,6 @@ class Horde_Text_Filter_Xss extends Horde_Text_Filter_Base
             $patterns[$pattern] = '<$1' . $this->_params['replace'] . '_tag';
         }
 
-        /* Strip out data URLs living in an A HREF element (Bug #8715). */
-        $malicious = '/<((?:a|&#0*65;?|&#0*41;?|&#0*97;?|&#0*61;?)\b[^>]+?)' .
-            '(?:h|&#0*72;?|&#0*48;?|&#0*104;?|&#0*68;?)\s*' .
-            '(?:r|&#0*82;?|&#x0*52;?|&#0*114;?|&#x0*72;?)\s*' .
-            '(?:e|&#0*69;?|&#0*45;?|&#0*101;?|&#0*65;?)\s*' .
-            '(?:f|&#0*70;?|&#0*46;?|&#0*102;?|&#0*66;?)\s*=' .
-            '("|\')?\s*data:(?(2)[^"\')>]*|[^\s)>]*)(?(2)\\2)/is';
-        $patterns[$malicious] = '<$1';
-
         /* Comment out style/link tags. */
         if ($this->_params['strip_styles']) {
             if ($this->_params['strip_style_attributes']) {
@@ -290,6 +281,20 @@ class Horde_Text_Filter_Xss extends Horde_Text_Filter_Base
      */
     public function postProcess($text)
     {
+        /* Strip out data URLs living in an A HREF element (Bug #8715).
+         * Done here because we need to match more than 1 possible data
+         * entry per tag. */
+        $data_from = '/<((?:a|&#0*65;?|&#0*41;?|&#0*97;?|&#0*61;?)\b[^>]+?)' .
+            '(?:h|&#0*72;?|&#0*48;?|&#0*104;?|&#0*68;?)\s*' .
+            '(?:r|&#0*82;?|&#x0*52;?|&#0*114;?|&#x0*72;?)\s*' .
+            '(?:e|&#0*69;?|&#0*45;?|&#0*101;?|&#0*65;?)\s*' .
+            '(?:f|&#0*70;?|&#0*46;?|&#0*102;?|&#0*66;?)\s*=' .
+            '("|\')?\s*data:(?(2)[^"\')>]*|[^\s)>]*)(?(2)\\2)/is';
+        $data_to = '<$1';
+        do {
+            $text = preg_replace($data_from, $data_to, $text, -1, $count);
+        } while ($count);
+
         ini_restore('pcre.backtrack_limit');
 
         // Restore CDATA data
diff --git a/framework/Text_Filter/test/Horde/Text/Filter/fixtures/xss95.html b/framework/Text_Filter/test/Horde/Text/Filter/fixtures/xss95.html
new file mode 100644 (file)
index 0000000..b7aa7ab
--- /dev/null
@@ -0,0 +1 @@
+<a href="data:text/html;base64,PGh0bWw+PGhlYWQ+PHRpdGxlPnRlc3Q8L3RpdGxlPjwvaGVhZD48Ym9keT48c2NyaXB0PmFsZXJ0KCd4c3M6ICcgKyBkb2N1bWVudC5jb29raWUpPC9zY3JpcHQ+PC9ib2R5PjwvaHRtbD4=" href="data:text/html;base64,PGh0bWw+PGhlYWQ+PHRpdGxlPnRlc3Q8L3RpdGxlPjwvaGVhZD48Ym9keT48c2NyaXB0PmFsZXJ0KCd4c3M6ICcgKyBkb2N1bWVudC5jb29raWUpPC9zY3JpcHQ+PC9ib2R5PjwvaHRtbD4=">Click me</a>
index b44afaa..c63ec0d 100644 (file)
@@ -222,6 +222,8 @@ xss84.html
 <XSSCleaned_script />
 xss85.html
 <XSSCleaned_script />PT SRC="http://ha.ckers.org/a.js"></XSSCleaned_tag>
+xss95.html
+<a  >Click me</a>
 xss96.html
 <a >Click me</a>
 xss97.html