(bug 27093, CVE-2011-0047): Fixed CSS injection vulnerability. The StringUtils.php...
authorTim Starling <tstarling@users.mediawiki.org>
Tue, 1 Feb 2011 22:36:43 +0000 (22:36 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Tue, 1 Feb 2011 22:36:43 +0000 (22:36 +0000)
includes/Sanitizer.php
includes/StringUtils.php

index ab67010..9585f9a 100644 (file)
@@ -747,6 +747,13 @@ class Sanitizer {
                // Remove any comments; IE gets token splitting wrong
                $value = StringUtils::delimiterReplace( '/*', '*/', ' ', $value );
 
+               // Remove anything after a comment-start token, to guard against
+               // incorrect client implementations.
+               $commentPos = strpos( $value, '/*' );
+               if ( $commentPos !== false ) {
+                       $value = substr( $value, 0, $commentPos );
+               }
+
                // Decode escape sequences and line continuation
                // See the grammar in the CSS 2 spec, appendix D.
                static $decodeRegex;
index 4c742e0..c1e617a 100644 (file)
@@ -81,16 +81,20 @@ class StringUtils {
                        }
 
                        if ( $tokenType == 'start' ) {
-                               $inputPos = $tokenOffset + $tokenLength;
                                # Only move the start position if we haven't already found a start
                                # This means that START START END matches outer pair
                                if ( !$foundStart ) {
                                        # Found start
+                                       $inputPos = $tokenOffset + $tokenLength;
                                        # Write out the non-matching section
                                        $output .= substr( $subject, $outputPos, $tokenOffset - $outputPos );
                                        $outputPos = $tokenOffset;
                                        $contentPos = $inputPos;
                                        $foundStart = true;
+                               } else {
+                                       # Move the input position past the *first character* of START,
+                                       # to protect against missing END when it overlaps with START
+                                       $inputPos = $tokenOffset + 1;
                                }
                        } elseif ( $tokenType == 'end' ) {
                                if ( $foundStart ) {