Title: [195073] trunk
Revision
195073
Author
[email protected]
Date
2016-01-14 13:37:49 -0800 (Thu, 14 Jan 2016)

Log Message

[XSS Auditor] Partial bypass when web server collapses path components
https://bugs.webkit.org/show_bug.cgi?id=152872

Reviewed by Brent Fulgham.

Merged from Blink (patch by Tom Sepez <[email protected]>):
<https://src.chromium.org/viewvc/blink?revision=167610&view=revision>

Source/WebCore:

Test: http/tests/security/xssAuditor/embed-tag-in-path-unterminated.html

* html/parser/XSSAuditor.cpp:
(WebCore::isNonCanonicalCharacter):
(WebCore::XSSAuditor::init):
(WebCore::XSSAuditor::decodedSnippetForName):
(WebCore::XSSAuditor::decodedSnippetForAttribute):
(WebCore::XSSAuditor::decodedSnippetForJavaScript):
(WebCore::fullyDecodeString): Deleted.

LayoutTests:

* http/tests/security/xssAuditor/embed-tag-in-path-unterminated-expected.txt: Added.
* http/tests/security/xssAuditor/embed-tag-in-path-unterminated.html: Added.
* http/tests/security/xssAuditor/intercept/.htaccess:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (195072 => 195073)


--- trunk/LayoutTests/ChangeLog	2016-01-14 21:31:05 UTC (rev 195072)
+++ trunk/LayoutTests/ChangeLog	2016-01-14 21:37:49 UTC (rev 195073)
@@ -1,3 +1,17 @@
+2016-01-14  Daniel Bates  <[email protected]>
+
+        [XSS Auditor] Partial bypass when web server collapses path components
+        https://bugs.webkit.org/show_bug.cgi?id=152872
+
+        Reviewed by Brent Fulgham.
+
+        Merged from Blink (patch by Tom Sepez <[email protected]>):
+        <https://src.chromium.org/viewvc/blink?revision=167610&view=revision>
+
+        * http/tests/security/xssAuditor/embed-tag-in-path-unterminated-expected.txt: Added.
+        * http/tests/security/xssAuditor/embed-tag-in-path-unterminated.html: Added.
+        * http/tests/security/xssAuditor/intercept/.htaccess:
+
 2016-01-14  Zalan Bujtas  <[email protected]>
 
         [iOS Simulator] fast/table/003.html failing

Added: trunk/LayoutTests/http/tests/security/xssAuditor/embed-tag-in-path-unterminated-expected.txt (0 => 195073)


--- trunk/LayoutTests/http/tests/security/xssAuditor/embed-tag-in-path-unterminated-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/embed-tag-in-path-unterminated-expected.txt	2016-01-14 21:37:49 UTC (rev 195073)
@@ -0,0 +1,4 @@
+CONSOLE MESSAGE: line 4: The XSS Auditor refused to execute a script in 'http://localhost:8000/security/xssAuditor/intercept/echo-intertag.pl/%3Cembed%20height=%22500%22src=%22https://127.0.0.1:8443/security/xssAuditor/resources/dummy.swf%22.xml&clutter=%3Cp%3E' because its source code was found within the request. The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header.
+Check that the XSSAuditor catches reflected tags in path components
+
+

Added: trunk/LayoutTests/http/tests/security/xssAuditor/embed-tag-in-path-unterminated.html (0 => 195073)


--- trunk/LayoutTests/http/tests/security/xssAuditor/embed-tag-in-path-unterminated.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/embed-tag-in-path-unterminated.html	2016-01-14 21:37:49 UTC (rev 195073)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner) {
+  testRunner.dumpAsText();
+  testRunner.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<p>Check that the XSSAuditor catches reflected tags in path components</p>
+<iframe src="" height=%22500%22src=%22https://127.0.0.1:8443/security/xssAuditor/resources/dummy.swf%22.xml&clutter=<p>"></iframe>
+</body>
+</html>

Modified: trunk/LayoutTests/http/tests/security/xssAuditor/intercept/.htaccess (195072 => 195073)


--- trunk/LayoutTests/http/tests/security/xssAuditor/intercept/.htaccess	2016-01-14 21:31:05 UTC (rev 195072)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/intercept/.htaccess	2016-01-14 21:37:49 UTC (rev 195073)
@@ -1,2 +1,5 @@
+# For ease in testing path reflections, pass any path component containing <'"
+# (and subsequent characters) as the "q" query parameter to the script identified
+# by the path components preceeding it.
 RewriteEngine on
-RewriteRule ^(.*)/(.*) /security/xssAuditor/resources/$1?q=$2 [L,NS]
+RewriteRule ^([^<"']*)/(.*) /security/xssAuditor/resources/$1?q=$2 [L,NS]

Modified: trunk/Source/WebCore/ChangeLog (195072 => 195073)


--- trunk/Source/WebCore/ChangeLog	2016-01-14 21:31:05 UTC (rev 195072)
+++ trunk/Source/WebCore/ChangeLog	2016-01-14 21:37:49 UTC (rev 195073)
@@ -1,3 +1,23 @@
+2016-01-14  Daniel Bates  <[email protected]>
+
+        [XSS Auditor] Partial bypass when web server collapses path components
+        https://bugs.webkit.org/show_bug.cgi?id=152872
+
+        Reviewed by Brent Fulgham.
+
+        Merged from Blink (patch by Tom Sepez <[email protected]>):
+        <https://src.chromium.org/viewvc/blink?revision=167610&view=revision>
+
+        Test: http/tests/security/xssAuditor/embed-tag-in-path-unterminated.html
+
+        * html/parser/XSSAuditor.cpp:
+        (WebCore::isNonCanonicalCharacter):
+        (WebCore::XSSAuditor::init):
+        (WebCore::XSSAuditor::decodedSnippetForName):
+        (WebCore::XSSAuditor::decodedSnippetForAttribute):
+        (WebCore::XSSAuditor::decodedSnippetForJavaScript):
+        (WebCore::fullyDecodeString): Deleted.
+
 2016-01-14  Beth Dakin  <[email protected]>
 
         imported/blink/editing/text-iterator/read-past-cloned-first-letter.html 

Modified: trunk/Source/WebCore/html/parser/XSSAuditor.cpp (195072 => 195073)


--- trunk/Source/WebCore/html/parser/XSSAuditor.cpp	2016-01-14 21:31:05 UTC (rev 195072)
+++ trunk/Source/WebCore/html/parser/XSSAuditor.cpp	2016-01-14 21:37:49 UTC (rev 195073)
@@ -56,9 +56,11 @@
     // Note, we don't remove backslashes like PHP stripslashes(), which among other things converts "\\0" to the \0 character.
     // Instead, we remove backslashes and zeros (since the string "\\0" =(remove backslashes)=> "0"). However, this has the
     // adverse effect that we remove any legitimate zeros from a string.
+    // We also remove forward-slash, because it is common for some servers to collapse successive path components, eg,
+    // a//b becomes a/b.
     //
-    // For instance: new String("http://localhost:8000") => new String("http://localhost:8").
-    return (c == '\\' || c == '0' || c == '\0' || c >= 127);
+    // For instance: new String("http://localhost:8000") => new String("http:localhost:8").
+    return (c == '\\' || c == '0' || c == '\0' || c == '/' || c >= 127);
 }
 
 static String canonicalize(const String& string)
@@ -175,7 +177,6 @@
         workingString = decode16BitUnicodeEscapeSequences(decodeStandardURLEscapeSequences(workingString, encoding));
     } while (workingString.length() < oldWorkingStringLength);
     workingString.replace('+', ' ');
-    workingString = canonicalize(workingString);
     return workingString;
 }
 
@@ -268,7 +269,7 @@
     if (document->decoder())
         m_encoding = document->decoder()->encoding();
 
-    m_decodedURL = fullyDecodeString(m_documentURL.string(), m_encoding);
+    m_decodedURL = canonicalize(fullyDecodeString(m_documentURL.string(), m_encoding));
     if (m_decodedURL.find(isRequiredForInjection) == notFound)
         m_decodedURL = String();
 
@@ -306,7 +307,7 @@
         if (httpBody && !httpBody->isEmpty()) {
             httpBodyAsString = httpBody->flattenToString();
             if (!httpBodyAsString.isEmpty()) {
-                m_decodedHTTPBody = fullyDecodeString(httpBodyAsString, m_encoding);
+                m_decodedHTTPBody = canonicalize(fullyDecodeString(httpBodyAsString, m_encoding));
                 if (m_decodedHTTPBody.find(isRequiredForInjection) == notFound)
                     m_decodedHTTPBody = String();
                 if (m_decodedHTTPBody.length() >= minimumLengthForSuffixTree)
@@ -567,7 +568,7 @@
 String XSSAuditor::decodedSnippetForName(const FilterTokenRequest& request)
 {
     // Grab a fixed number of characters equal to the length of the token's name plus one (to account for the "<").
-    return fullyDecodeString(request.sourceTracker.source(request.token), m_encoding).substring(0, request.token.name().size() + 1);
+    return canonicalize(fullyDecodeString(request.sourceTracker.source(request.token), m_encoding).substring(0, request.token.name().size() + 1));
 }
 
 String XSSAuditor::decodedSnippetForAttribute(const FilterTokenRequest& request, const HTMLToken::Attribute& attribute, AttributeKind treatment)
@@ -578,6 +579,9 @@
     // FIXME: We should grab one character before the name also.
     unsigned start = attribute.startOffset;
     unsigned end = attribute.endOffset;
+
+    // We defer canonicalizing the decoded string here to preserve embedded slashes (if any) that
+    // may lead us to truncate the string.
     String decodedSnippet = fullyDecodeString(request.sourceTracker.source(request.token, start, end), m_encoding);
     decodedSnippet.truncate(kMaximumFragmentLengthTarget);
     if (treatment == SrcLikeAttribute) {
@@ -626,7 +630,7 @@
             decodedSnippet.truncate(position);
         }
     }
-    return decodedSnippet;
+    return canonicalize(decodedSnippet);
 }
 
 String XSSAuditor::decodedSnippetForJavaScript(const FilterTokenRequest& request)
@@ -697,7 +701,7 @@
                 lastNonSpacePosition = foundPosition;
         }
 
-        result = fullyDecodeString(string.substring(startPosition, foundPosition - startPosition), m_encoding);
+        result = canonicalize(fullyDecodeString(string.substring(startPosition, foundPosition - startPosition), m_encoding));
         startPosition = foundPosition + 1;
     }
     return result;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to