Title: [95065] trunk
Revision
95065
Author
commit-qu...@webkit.org
Date
2011-09-13 18:19:04 -0700 (Tue, 13 Sep 2011)

Log Message

Fix XSS auditor bypass when inline handlers contain comments.
https://bugs.webkit.org/show_bug.cgi?id=27895

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

Source/WebCore:

Tests: http/tests/security/xssAuditor/property-escape-comment.html
       http/tests/security/xssAuditor/property-escape-entity.html
       http/tests/security/xssAuditor/property-escape-quote.html

* html/parser/XSSAuditor.cpp:
(WebCore::XSSAuditor::snippetForAttribute):

LayoutTests:

* http/tests/security/xssAuditor/malformed-HTML-expected.txt:
* http/tests/security/xssAuditor/open-attribute-body-expected.txt:
* http/tests/security/xssAuditor/open-event-handler-iframe-expected.txt:
* http/tests/security/xssAuditor/property-escape-comment-expected.txt: Added.
* http/tests/security/xssAuditor/property-escape-comment.html: Added.
* http/tests/security/xssAuditor/property-escape-entity-expected.txt: Added.
* http/tests/security/xssAuditor/property-escape-entity.html: Added.
* http/tests/security/xssAuditor/property-escape-quote-expected.txt: Added.
* http/tests/security/xssAuditor/property-escape-quote.html: Added.
* http/tests/security/xssAuditor/resources/echo-property.pl:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (95064 => 95065)


--- trunk/LayoutTests/ChangeLog	2011-09-14 01:13:59 UTC (rev 95064)
+++ trunk/LayoutTests/ChangeLog	2011-09-14 01:19:04 UTC (rev 95065)
@@ -1,3 +1,21 @@
+2011-09-13  Tom Sepez  <tse...@chromium.org>
+
+        Fix XSS auditor bypass when inline handlers contain comments.
+        https://bugs.webkit.org/show_bug.cgi?id=27895
+
+        Reviewed by Adam Barth.
+
+        * http/tests/security/xssAuditor/malformed-HTML-expected.txt:
+        * http/tests/security/xssAuditor/open-attribute-body-expected.txt:
+        * http/tests/security/xssAuditor/open-event-handler-iframe-expected.txt:
+        * http/tests/security/xssAuditor/property-escape-comment-expected.txt: Added.
+        * http/tests/security/xssAuditor/property-escape-comment.html: Added.
+        * http/tests/security/xssAuditor/property-escape-entity-expected.txt: Added.
+        * http/tests/security/xssAuditor/property-escape-entity.html: Added.
+        * http/tests/security/xssAuditor/property-escape-quote-expected.txt: Added.
+        * http/tests/security/xssAuditor/property-escape-quote.html: Added.
+        * http/tests/security/xssAuditor/resources/echo-property.pl:
+
 2011-09-13  Fumitoshi Ukai  <u...@chromium.org>
 
         Update chromium-mac test expectations

Modified: trunk/LayoutTests/http/tests/security/xssAuditor/malformed-HTML-expected.txt (95064 => 95065)


--- trunk/LayoutTests/http/tests/security/xssAuditor/malformed-HTML-expected.txt	2011-09-14 01:13:59 UTC (rev 95064)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/malformed-HTML-expected.txt	2011-09-14 01:19:04 UTC (rev 95065)
@@ -1,5 +1,7 @@
+CONSOLE MESSAGE: line 1: Refused to execute a _javascript_ script. Source code of script found within request.
 
 
+
 --------
 Frame: '<!--framePath //<!--frame0-->-->'
 --------

Modified: trunk/LayoutTests/http/tests/security/xssAuditor/open-attribute-body-expected.txt (95064 => 95065)


--- trunk/LayoutTests/http/tests/security/xssAuditor/open-attribute-body-expected.txt	2011-09-14 01:13:59 UTC (rev 95064)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/open-attribute-body-expected.txt	2011-09-14 01:19:04 UTC (rev 95065)
@@ -1,2 +1,3 @@
-ALERT: /XSS/
+CONSOLE MESSAGE: line 1: Refused to execute a _javascript_ script. Source code of script found within request.
 
+

Modified: trunk/LayoutTests/http/tests/security/xssAuditor/open-event-handler-iframe-expected.txt (95064 => 95065)


--- trunk/LayoutTests/http/tests/security/xssAuditor/open-event-handler-iframe-expected.txt	2011-09-14 01:13:59 UTC (rev 95064)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/open-event-handler-iframe-expected.txt	2011-09-14 01:19:04 UTC (rev 95065)
@@ -1,2 +1,3 @@
-ALERT: /XSS/
+CONSOLE MESSAGE: line 1: Refused to execute a _javascript_ script. Source code of script found within request.
 
+

Added: trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-comment-expected.txt (0 => 95065)


--- trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-comment-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-comment-expected.txt	2011-09-14 01:19:04 UTC (rev 95065)
@@ -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/property-escape-comment.html (0 => 95065)


--- trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-comment.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-comment.html	2011-09-14 01:19:04 UTC (rev 95065)
@@ -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/property-escape-entity-expected.txt (0 => 95065)


--- trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-entity-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-entity-expected.txt	2011-09-14 01:19:04 UTC (rev 95065)
@@ -0,0 +1,7 @@
+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.
+
+CONSOLE MESSAGE: line 1: Refused to execute a _javascript_ script. Source code of script found within request.
+
+  

Added: trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-entity.html (0 => 95065)


--- trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-entity.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-entity.html	2011-09-14 01:19:04 UTC (rev 95065)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src=""
+</iframe>
+<iframe src=""
+</iframe>
+<iframe src=""
+</iframe>
+</iframe>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-quote-expected.txt (0 => 95065)


--- trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-quote-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-quote-expected.txt	2011-09-14 01:19:04 UTC (rev 95065)
@@ -0,0 +1,7 @@
+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.
+
+CONSOLE MESSAGE: line 1: Refused to execute a _javascript_ script. Source code of script found within request.
+
+  

Added: trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-quote.html (0 => 95065)


--- trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-quote.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/property-escape-quote.html	2011-09-14 01:19:04 UTC (rev 95065)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src=""
+</iframe>
+<iframe src=""
+</iframe>
+<iframe src=""
+</iframe>
+</body>
+</html>

Modified: trunk/LayoutTests/http/tests/security/xssAuditor/resources/echo-property.pl (95064 => 95065)


--- trunk/LayoutTests/http/tests/security/xssAuditor/resources/echo-property.pl	2011-09-14 01:13:59 UTC (rev 95064)
+++ trunk/LayoutTests/http/tests/security/xssAuditor/resources/echo-property.pl	2011-09-14 01:19:04 UTC (rev 95065)
@@ -10,6 +10,9 @@
 print "<html>\n";
 print "<body foo=\"";
 print $cgi->param('q');
+if ($cgi->param('clutter')) {
+    print $cgi->param('clutter');
+}
 print "\">\n";
 print "</body>\n";
 print "</html>\n";

Modified: trunk/Source/WebCore/ChangeLog (95064 => 95065)


--- trunk/Source/WebCore/ChangeLog	2011-09-14 01:13:59 UTC (rev 95064)
+++ trunk/Source/WebCore/ChangeLog	2011-09-14 01:19:04 UTC (rev 95065)
@@ -1,3 +1,17 @@
+2011-09-13  Tom Sepez  <tse...@chromium.org>
+
+        Fix XSS auditor bypass when inline handlers contain comments.
+        https://bugs.webkit.org/show_bug.cgi?id=27895
+
+        Reviewed by Adam Barth.
+
+        Tests: http/tests/security/xssAuditor/property-escape-comment.html
+               http/tests/security/xssAuditor/property-escape-entity.html
+               http/tests/security/xssAuditor/property-escape-quote.html
+
+        * html/parser/XSSAuditor.cpp:
+        (WebCore::XSSAuditor::snippetForAttribute):
+
 2011-09-13  Kentaro Hara  <hara...@google.com>
 
         Implement a HashChangeEvent constructor for V8

Modified: trunk/Source/WebCore/html/parser/XSSAuditor.cpp (95064 => 95065)


--- trunk/Source/WebCore/html/parser/XSSAuditor.cpp	2011-09-14 01:13:59 UTC (rev 95064)
+++ trunk/Source/WebCore/html/parser/XSSAuditor.cpp	2011-09-14 01:19:04 UTC (rev 95065)
@@ -70,6 +70,16 @@
     return (c == '\'' || c == '"' || c == '<' || c == '>');
 }
 
+static bool isTerminatingCharacter(UChar c) 
+{
+    return (c == '&' || c == '/' || c == '"' || c == '\'');
+}
+
+static bool isHTMLQuote(UChar c)
+{
+    return (c == '"' || c == '\'');
+}
+
 static bool hasName(const HTMLToken& token, const QualifiedName& name)
 {
     return equalIgnoringNullity(token.name(), static_cast<const String&>(name.localName()));
@@ -468,11 +478,37 @@
 
 String XSSAuditor::snippetForAttribute(const HTMLToken& token, const HTMLToken::Attribute& attribute)
 {
+    // The range doesn't inlcude the character which terminates the value. So,
+    // for an input of |name="value"|, the snippet is |name="value|. For an
+    // unquoted input of |name=value |, the snippet is |name=value|.
     // FIXME: We should grab one character before the name also.
     int start = attribute.m_nameRange.m_start - token.startIndex();
-    // FIXME: We probably want to grab only the first few characters of the attribute value.
     int end = attribute.m_valueRange.m_end - token.startIndex();
-    return snippetForRange(token, start, end);
+    String snippet = snippetForRange(token, start, end);
+
+    // Beware of trailing characters which came from the page itself, not the 
+    // injected vector. Excluding the terminating character covers common cases
+    // where the page immediately ends the attribute, but doesn't cover more
+    // complex cases where there is other page data following the injection. 
+    // Generally, these won't parse as _javascript_, so the injected vector
+    // typically excludes them from consideration via a single-line comment or
+    // by enclosing them in a string literal terminated later by the page's own
+    // closing punctuation. Since the snippet has not been parsed, the vector
+    // may also try to introduce these via entities. As a result, we'd like to
+    // stop before the first "//", the first entity, or the first quote not
+    // immediately following the first equals sign (taking whitespace into
+    // consideration). To keep things simpler, we don't try to distinguish
+    // between entity-introducing amperands vs. other uses, nor do we bother to
+    // check for a second slash for a comment, stoping instead on any ampersand
+    // or slash.
+    size_t position;
+    if ((position = snippet.find("=")) != notFound
+        && (position = snippet.find(isNotHTMLSpace, position + 1)) != notFound
+        && (position = snippet.find(isTerminatingCharacter, isHTMLQuote(snippet[position]) ? position + 1 : position)) != notFound) {
+        snippet.truncate(position);
+    }
+
+    return snippet;
 }
 
 bool XSSAuditor::isContainedInRequest(const String& snippet)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to