Title: [95774] trunk
Revision
95774
Author
commit-qu...@webkit.org
Date
2011-09-22 19:28:31 -0700 (Thu, 22 Sep 2011)

Log Message

Make XSSAuditor extract meaningful snippet from script blocks for comparison
against the URL when checking for reflection.  Avoids getting caugh up in
trailing comments.
https://bugs.webkit.org/show_bug.cgi?id=68094

Patch by Tom Sepez <tse...@chromium.org> on 2011-09-22
Reviewed by Adam Barth.

Source/WebCore:

Tests: http/tests/security/xssAuditor/script-tag-with-trailing-comment.html
       http/tests/security/xssAuditor/script-tag-with-trailing-comment2.html
       http/tests/security/xssAuditor/script-tag-with-trailing-comment3.html

* html/parser/XSSAuditor.cpp:
(WebCore::XSSAuditor::filterTokenAfterScriptStartTag):
(WebCore::XSSAuditor::extractCodeFragment):
* html/parser/XSSAuditor.h:

LayoutTests:

* http/tests/security/xssAuditor/resources/echo-intertag.pl:
* http/tests/security/xssAuditor/script-tag-with-trailing-comment-expected.txt: Added.
* http/tests/security/xssAuditor/script-tag-with-trailing-comment.html: Added.
* http/tests/security/xssAuditor/script-tag-with-trailing-comment2-expected.txt: Added.
* http/tests/security/xssAuditor/script-tag-with-trailing-comment2.html: Added.
* http/tests/security/xssAuditor/script-tag-with-trailing-comment3-expected.txt: Added.
* http/tests/security/xssAuditor/script-tag-with-trailing-comment3.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (95773 => 95774)


--- trunk/LayoutTests/ChangeLog	2011-09-23 02:27:59 UTC (rev 95773)
+++ trunk/LayoutTests/ChangeLog	2011-09-23 02:28:31 UTC (rev 95774)
@@ -1,3 +1,20 @@
+2011-09-22  Tom Sepez  <tse...@chromium.org>
+
+        Make XSSAuditor extract meaningful snippet from script blocks for comparison
+        against the URL when checking for reflection.  Avoids getting caugh up in
+        trailing comments.
+        https://bugs.webkit.org/show_bug.cgi?id=68094
+
+        Reviewed by Adam Barth.
+
+        * http/tests/security/xssAuditor/resources/echo-intertag.pl:
+        * http/tests/security/xssAuditor/script-tag-with-trailing-comment-expected.txt: Added.
+        * http/tests/security/xssAuditor/script-tag-with-trailing-comment.html: Added.
+        * http/tests/security/xssAuditor/script-tag-with-trailing-comment2-expected.txt: Added.
+        * http/tests/security/xssAuditor/script-tag-with-trailing-comment2.html: Added.
+        * http/tests/security/xssAuditor/script-tag-with-trailing-comment3-expected.txt: Added.
+        * http/tests/security/xssAuditor/script-tag-with-trailing-comment3.html: Added.
+
 2011-09-22  Ben Wells  <benwe...@chromium.org>
 
         Rebaseline for bug 65583 (path based border radius drawing on skia) part 5

Modified: trunk/LayoutTests/http/tests/security/xssAuditor/resources/echo-intertag.pl (95773 => 95774)


--- trunk/LayoutTests/http/tests/security/xssAuditor/resources/echo-intertag.pl	2011-09-23 02:27:59 UTC (rev 95773)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/resources/echo-intertag.pl	2011-09-23 02:28:31 UTC (rev 95774)
@@ -35,6 +35,9 @@
 if ($cgi->param('clutter')) {
     print $cgi->param('clutter');
 }
+if ($cgi->param('q2')) {
+    print $cgi->param('q2');
+}
 if ($cgi->param('notifyDone')) {
     print "<script>\n";
     print "if (window.layoutTestController)\n";

Added: trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment-expected.txt (0 => 95774)


--- trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment-expected.txt	2011-09-23 02:28:31 UTC (rev 95774)
@@ -0,0 +1,3 @@
+CONSOLE MESSAGE: line 1: Refused to execute a _javascript_ script. Source code of script found within request.
+
+

Added: trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment.html (0 => 95774)


--- trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment.html	2011-09-23 02:28:31 UTC (rev 95774)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src=""
+</iframe>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment2-expected.txt (0 => 95774)


--- trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment2-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment2-expected.txt	2011-09-23 02:28:31 UTC (rev 95774)
@@ -0,0 +1,5 @@
+CONSOLE MESSAGE: line 1: Refused to execute a _javascript_ script. Source code of script found within request.
+
+CONSOLE MESSAGE: line 1: Refused to execute a _javascript_ script. Source code of script found within request.
+
+ 

Added: trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment2.html (0 => 95774)


--- trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment2.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment2.html	2011-09-23 02:28:31 UTC (rev 95774)
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src=""
+</iframe>
+<iframe src=""
+</iframe>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment3-expected.txt (0 => 95774)


--- trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment3-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment3-expected.txt	2011-09-23 02:28:31 UTC (rev 95774)
@@ -0,0 +1,3 @@
+CONSOLE MESSAGE: line 1: Refused to execute a _javascript_ script. Source code of script found within request.
+
+

Added: trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment3.html (0 => 95774)


--- trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment3.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/script-tag-with-trailing-comment3.html	2011-09-23 02:28:31 UTC (rev 95774)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src=""
+</iframe>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (95773 => 95774)


--- trunk/Source/WebCore/ChangeLog	2011-09-23 02:27:59 UTC (rev 95773)
+++ trunk/Source/WebCore/ChangeLog	2011-09-23 02:28:31 UTC (rev 95774)
@@ -1,3 +1,21 @@
+2011-09-22  Tom Sepez  <tse...@chromium.org>
+
+        Make XSSAuditor extract meaningful snippet from script blocks for comparison
+        against the URL when checking for reflection.  Avoids getting caugh up in
+        trailing comments.
+        https://bugs.webkit.org/show_bug.cgi?id=68094
+
+        Reviewed by Adam Barth.
+
+        Tests: http/tests/security/xssAuditor/script-tag-with-trailing-comment.html
+               http/tests/security/xssAuditor/script-tag-with-trailing-comment2.html
+               http/tests/security/xssAuditor/script-tag-with-trailing-comment3.html
+
+        * html/parser/XSSAuditor.cpp:
+        (WebCore::XSSAuditor::filterTokenAfterScriptStartTag):
+        (WebCore::XSSAuditor::extractCodeFragment):
+        * html/parser/XSSAuditor.h:
+
 2011-09-22  Nate Chapin  <jap...@chromium.org>
 
         Remove didReceiveAuthenticationChallenge() from SubresourceLoaderClient.

Modified: trunk/Source/WebCore/html/parser/XSSAuditor.cpp (95773 => 95774)


--- trunk/Source/WebCore/html/parser/XSSAuditor.cpp	2011-09-23 02:27:59 UTC (rev 95773)
+++ trunk/Source/WebCore/html/parser/XSSAuditor.cpp	2011-09-23 02:28:31 UTC (rev 95774)
@@ -80,6 +80,26 @@
     return (c == '"' || c == '\'');
 }
 
+static bool isHTMLNewline(UChar c)
+{
+    return (c == '\n' || c == '\r');
+}
+
+static bool startsHTMLCommentAt(const String& string, size_t start)
+{
+    return (start + 3 < string.length() && string[start] == '<' && string[start+1] == '!' && string[start+2] == '-' && string[start+3] == '-');
+}    
+
+static bool startsSingleLineCommentAt(const String& string, size_t start)
+{
+    return (start + 1 < string.length() && string[start] == '/' && string[start+1] == '/');
+}    
+
+static bool startsMultiLineCommentAt(const String& string, size_t start)
+{
+    return (start + 1 < string.length() && string[start] == '/' && string[start+1] == '*');
+}
+
 static bool hasName(const HTMLToken& token, const QualifiedName& name)
 {
     return equalIgnoringNullity(token.name(), static_cast<const String&>(name.localName()));
@@ -305,15 +325,16 @@
         return false;
     }
 
-    int start = 0;
-    // FIXME: We probably want to grab only the first few characters of the
-    //        contents of the script element.
-    int end = token.endIndex() - token.startIndex();
-    String snippet = m_cachedSnippet + snippetForRange(token, start, end);
-    if (isContainedInRequest(fullyDecodeString(snippet, m_parser->document()->decoder()))) {
-        token.eraseCharacters();
-        token.appendToCharacter(' '); // Technically, character tokens can't be empty.
-        return true;
+    TextResourceDecoder* decoder = m_parser->document()->decoder();
+    if (isContainedInRequest(fullyDecodeString(m_cachedSnippet, decoder))) {
+        int start = 0;
+        int end = token.endIndex() - token.startIndex();
+        String snippet = snippetForJavaScript(snippetForRange(token, start, end));
+        if (isContainedInRequest(fullyDecodeString(snippet, decoder))) {
+            token.eraseCharacters();
+            token.appendToCharacter(' '); // Technically, character tokens can't be empty.
+            return true;
+        }
     }
     return false;
 }
@@ -537,4 +558,50 @@
     return (m_parser->document()->url().host() == resourceURL.host() && resourceURL.query().isEmpty());
 }
 
+
+String XSSAuditor::snippetForJavaScript(const String& string)
+{
+    const size_t kMaximumFragmentLengthTarget = 100;
+
+    size_t startPosition = 0;
+    size_t endPosition = string.length();
+    size_t foundPosition = notFound;
+
+    // Skip over initial comments to find start of code.
+    while (startPosition < endPosition) {
+        while (startPosition < endPosition && isHTMLSpace(string[startPosition]))
+            startPosition++;
+        if (startsHTMLCommentAt(string, startPosition) || startsSingleLineCommentAt(string, startPosition)) {
+            while (startPosition < endPosition && !isHTMLNewline(string[startPosition]))
+                startPosition++;
+        } else if (startsMultiLineCommentAt(string, startPosition)) {
+            if ((foundPosition = string.find("*/", startPosition)) != notFound)
+                startPosition = foundPosition + 2;
+            else
+                startPosition = endPosition;
+        } else
+            break;
+    }
+
+    // Stop at next comment or when we exceed the maximum length target. After hitting the
+    // length target, we can only stop at a point where we know we are not in the middle of
+    // a %-escape sequence. A simple way to do this is to break on whitespace only.                
+    for (foundPosition = startPosition; foundPosition < endPosition; foundPosition++) {
+        if (startsSingleLineCommentAt(string, foundPosition) || startsMultiLineCommentAt(string, foundPosition)) {
+            endPosition = foundPosition + 2;
+            break;
+        }
+        if (startsHTMLCommentAt(string, foundPosition)) {
+            endPosition = foundPosition + 4;
+            break;
+        }
+        if (foundPosition > startPosition + kMaximumFragmentLengthTarget && isHTMLSpace(string[foundPosition])) {
+            endPosition = foundPosition;
+            break;
+        }
+    }
+    
+    return string.substring(startPosition, endPosition - startPosition);
 }
+
+} // namespace WebCore

Modified: trunk/Source/WebCore/html/parser/XSSAuditor.h (95773 => 95774)


--- trunk/Source/WebCore/html/parser/XSSAuditor.h	2011-09-23 02:27:59 UTC (rev 95773)
+++ trunk/Source/WebCore/html/parser/XSSAuditor.h	2011-09-23 02:28:31 UTC (rev 95774)
@@ -67,6 +67,7 @@
     bool eraseAttributeIfInjected(HTMLToken&, const QualifiedName&, const String& replacementValue = String());
 
     String snippetForRange(const HTMLToken&, int start, int end);
+    String snippetForJavaScript(const String&);
     String decodedSnippetForAttribute(const HTMLToken&, const HTMLToken::Attribute&);
 
     bool isContainedInRequest(const String&);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to