[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.15.1-1414-gc69ee75

dbates at webkit.org dbates at webkit.org
Thu Oct 29 20:45:34 UTC 2009


The following commit has been merged in the webkit-1.1 branch:
commit 5509c305c29472a004ff5e31866d41d6a10223d5
Author: dbates at webkit.org <dbates at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Oct 15 19:04:57 2009 +0000

    2009-10-15  Daniel Bates  <dbates at webkit.org>
    
            Reviewed by Adam Barth.
    
            https://bugs.webkit.org/show_bug.cgi?id=27895
    
            Fixes an issue in which injecting an inline event handler whose value ends in a single-line
            JavaScript comment can bypass the XSSAuditor. Similarly fixes this issue with respect to
            the HTML Base element, HTML Object element, inline and external script tags, and
            JavaScript multi-line variants of all of these attacks.
    
            Tests: http/tests/security/xssAuditor/base-href-comment.html
                   http/tests/security/xssAuditor/iframe-javascript-url-comment.html
                   http/tests/security/xssAuditor/img-onerror-HTML-comment.html
                   http/tests/security/xssAuditor/img-onerror-comment.html
                   http/tests/security/xssAuditor/object-tag-comment.html
                   http/tests/security/xssAuditor/script-tag-comment-HTML-entity.html
                   http/tests/security/xssAuditor/script-tag-comment.html
                   http/tests/security/xssAuditor/script-tag-with-source-comment.html
    
            * page/XSSAuditor.cpp: Added constant minAttackLength.
            (WebCore::XSSAuditor::canEvaluate):
            (WebCore::XSSAuditor::canEvaluateJavaScriptURL):
            (WebCore::XSSAuditor::canCreateInlineEventListener):
            (WebCore::XSSAuditor::canLoadExternalScriptFromSrc):
            (WebCore::XSSAuditor::canLoadObject):
            (WebCore::XSSAuditor::canSetBaseElementURL):
            (WebCore::XSSAuditor::findInRequest): Added parameter context. Only looks at up
            to minAttackLength of script code plus context (if any).
            * page/XSSAuditor.h:
    2009-10-15  Daniel Bates  <dbates at webkit.org>
    
            Reviewed by Adam Barth.
    
            https://bugs.webkit.org/show_bug.cgi?id=27895
    
            Tests that inline event handlers whose value ends in a single-line JavaScript
            comment cannot bypass the XSSAuditor. Also tests that the XSSAuditor prevents
            similar attack vectors with respect to the HTML Base element, HTML Object
            element, and external JavaScripts.
    
            * http/tests/security/xssAuditor/base-href-comment-expected.txt: Added.
            * http/tests/security/xssAuditor/base-href-comment.html: Added.
            * http/tests/security/xssAuditor/iframe-javascript-url-comment-expected.txt: Added.
            * http/tests/security/xssAuditor/iframe-javascript-url-comment.html: Added.
            * http/tests/security/xssAuditor/img-onerror-HTML-comment-expected.txt: Added.
            * http/tests/security/xssAuditor/img-onerror-HTML-comment.html: Added.
            * http/tests/security/xssAuditor/img-onerror-comment-expected.txt: Added.
            * http/tests/security/xssAuditor/img-onerror-comment.html: Added.
            * http/tests/security/xssAuditor/object-tag-comment-expected.txt: Added.
            * http/tests/security/xssAuditor/object-tag-comment.html: Added.
            * http/tests/security/xssAuditor/resources/echo-before-image.pl: Added.
            * http/tests/security/xssAuditor/resources/echo-head-base-href-comment.pl: Added.
            * http/tests/security/xssAuditor/script-tag-comment-HTML-entity-expected.txt: Added.
            * http/tests/security/xssAuditor/script-tag-comment-HTML-entity.html: Added.
            * http/tests/security/xssAuditor/script-tag-comment-expected.txt: Added.
            * http/tests/security/xssAuditor/script-tag-comment.html: Added.
            * http/tests/security/xssAuditor/script-tag-with-source-comment-expected.txt: Added.
            * http/tests/security/xssAuditor/script-tag-with-source-comment.html: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@49644 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index b23d337..56b87b3 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,33 @@
+2009-10-15  Daniel Bates  <dbates at webkit.org>
+
+        Reviewed by Adam Barth.
+
+        https://bugs.webkit.org/show_bug.cgi?id=27895
+        
+        Tests that inline event handlers whose value ends in a single-line JavaScript
+        comment cannot bypass the XSSAuditor. Also tests that the XSSAuditor prevents
+        similar attack vectors with respect to the HTML Base element, HTML Object
+        element, and external JavaScripts.
+
+        * http/tests/security/xssAuditor/base-href-comment-expected.txt: Added.
+        * http/tests/security/xssAuditor/base-href-comment.html: Added.
+        * http/tests/security/xssAuditor/iframe-javascript-url-comment-expected.txt: Added.
+        * http/tests/security/xssAuditor/iframe-javascript-url-comment.html: Added.
+        * http/tests/security/xssAuditor/img-onerror-HTML-comment-expected.txt: Added.
+        * http/tests/security/xssAuditor/img-onerror-HTML-comment.html: Added.
+        * http/tests/security/xssAuditor/img-onerror-comment-expected.txt: Added.
+        * http/tests/security/xssAuditor/img-onerror-comment.html: Added.
+        * http/tests/security/xssAuditor/object-tag-comment-expected.txt: Added.
+        * http/tests/security/xssAuditor/object-tag-comment.html: Added.
+        * http/tests/security/xssAuditor/resources/echo-before-image.pl: Added.
+        * http/tests/security/xssAuditor/resources/echo-head-base-href-comment.pl: Added.
+        * http/tests/security/xssAuditor/script-tag-comment-HTML-entity-expected.txt: Added.
+        * http/tests/security/xssAuditor/script-tag-comment-HTML-entity.html: Added.
+        * http/tests/security/xssAuditor/script-tag-comment-expected.txt: Added.
+        * http/tests/security/xssAuditor/script-tag-comment.html: Added.
+        * http/tests/security/xssAuditor/script-tag-with-source-comment-expected.txt: Added.
+        * http/tests/security/xssAuditor/script-tag-with-source-comment.html: Added.
+
 2009-10-15  Brian Weinstein  <bweinstein at apple.com>
 
         Rubber-stamped by Adele Peterson.
diff --git a/LayoutTests/http/tests/security/xssAuditor/base-href-control-char-expected.txt b/LayoutTests/http/tests/security/xssAuditor/base-href-comment-expected.txt
similarity index 100%
copy from LayoutTests/http/tests/security/xssAuditor/base-href-control-char-expected.txt
copy to LayoutTests/http/tests/security/xssAuditor/base-href-comment-expected.txt
diff --git a/LayoutTests/http/tests/security/xssAuditor/base-href-comment.html b/LayoutTests/http/tests/security/xssAuditor/base-href-comment.html
new file mode 100644
index 0000000..d587772
--- /dev/null
+++ b/LayoutTests/http/tests/security/xssAuditor/base-href-comment.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src="http://localhost:8000/security/xssAuditor/resources/echo-head-base-href-comment.pl?q=<base href='http://127.0.0.1:8000/security/xssAuditor/resources/base-href/?">
+</iframe>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/xssAuditor/anchor-url-dom-write-location-expected.txt b/LayoutTests/http/tests/security/xssAuditor/iframe-javascript-url-comment-expected.txt
similarity index 100%
copy from LayoutTests/http/tests/security/xssAuditor/anchor-url-dom-write-location-expected.txt
copy to LayoutTests/http/tests/security/xssAuditor/iframe-javascript-url-comment-expected.txt
diff --git a/LayoutTests/http/tests/security/xssAuditor/iframe-javascript-url-comment.html b/LayoutTests/http/tests/security/xssAuditor/iframe-javascript-url-comment.html
new file mode 100644
index 0000000..e3bcecb
--- /dev/null
+++ b/LayoutTests/http/tests/security/xssAuditor/iframe-javascript-url-comment.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src='http://localhost:8000/security/xssAuditor/resources/echo-before-image.pl?q=%3Ciframe%20src=javascript:alert(document.domain)//'>
+</iframe>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/xssAuditor/anchor-url-dom-write-location-expected.txt b/LayoutTests/http/tests/security/xssAuditor/img-onerror-HTML-comment-expected.txt
similarity index 100%
copy from LayoutTests/http/tests/security/xssAuditor/anchor-url-dom-write-location-expected.txt
copy to LayoutTests/http/tests/security/xssAuditor/img-onerror-HTML-comment-expected.txt
diff --git a/LayoutTests/http/tests/security/xssAuditor/img-onerror-HTML-comment.html b/LayoutTests/http/tests/security/xssAuditor/img-onerror-HTML-comment.html
new file mode 100644
index 0000000..58ae003
--- /dev/null
+++ b/LayoutTests/http/tests/security/xssAuditor/img-onerror-HTML-comment.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src="http://localhost:8000/security/xssAuditor/resources/echo-before-image.pl?q=<img src=%22about%3Ablank%22 OnError %3D%22alert(/XSS/)%3B%3C%21--">
+</iframe>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/xssAuditor/anchor-url-dom-write-location-expected.txt b/LayoutTests/http/tests/security/xssAuditor/img-onerror-comment-expected.txt
similarity index 100%
copy from LayoutTests/http/tests/security/xssAuditor/anchor-url-dom-write-location-expected.txt
copy to LayoutTests/http/tests/security/xssAuditor/img-onerror-comment-expected.txt
diff --git a/LayoutTests/http/tests/security/xssAuditor/img-onerror-comment.html b/LayoutTests/http/tests/security/xssAuditor/img-onerror-comment.html
new file mode 100644
index 0000000..32b6631
--- /dev/null
+++ b/LayoutTests/http/tests/security/xssAuditor/img-onerror-comment.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src="http://localhost:8000/security/xssAuditor/resources/echo-before-image.pl?q=<img src=%22about%3Ablank%22 OnError %3D%22alert(/XSS/)%3B//">
+</iframe>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/xssAuditor/embed-tag-control-char-expected.txt b/LayoutTests/http/tests/security/xssAuditor/object-tag-comment-expected.txt
similarity index 100%
copy from LayoutTests/http/tests/security/xssAuditor/embed-tag-control-char-expected.txt
copy to LayoutTests/http/tests/security/xssAuditor/object-tag-comment-expected.txt
diff --git a/LayoutTests/http/tests/security/xssAuditor/object-tag-comment.html b/LayoutTests/http/tests/security/xssAuditor/object-tag-comment.html
new file mode 100644
index 0000000..fd67d2e
--- /dev/null
+++ b/LayoutTests/http/tests/security/xssAuditor/object-tag-comment.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src="http://localhost:8000/security/xssAuditor/resources/echo-before-image.pl?q=<object name='plugin' type='application/x-webkit-test-netscape'><param name='movie' value=%22http://127.0.0.1:8000/security/xssAuditor/resources/dummy.swf?">
+</iframe>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/xssAuditor/resources/echo-before-image.pl b/LayoutTests/http/tests/security/xssAuditor/resources/echo-before-image.pl
new file mode 100755
index 0000000..5f45b75
--- /dev/null
+++ b/LayoutTests/http/tests/security/xssAuditor/resources/echo-before-image.pl
@@ -0,0 +1,17 @@
+#!/usr/bin/perl -wT
+use strict;
+use CGI;
+
+my $cgi = new CGI;
+
+print "Content-Type: text/html; charset=UTF-8\n\n";
+
+print "<!DOCTYPE html>\n";
+print "<html>\n";
+print "<body>\n";
+print $cgi->param('q');
+print "<img src=\"dummy.jpg\">";
+print "<script></script>\n";
+print "<object></object>\n";
+print "</body>\n";
+print "</html>\n";
diff --git a/LayoutTests/http/tests/security/xssAuditor/resources/echo-head-base-href-comment.pl b/LayoutTests/http/tests/security/xssAuditor/resources/echo-head-base-href-comment.pl
new file mode 100755
index 0000000..1760e51
--- /dev/null
+++ b/LayoutTests/http/tests/security/xssAuditor/resources/echo-head-base-href-comment.pl
@@ -0,0 +1,18 @@
+#!/usr/bin/perl -wT
+use strict;
+use CGI;
+
+my $cgi = new CGI;
+
+print "Content-Type: text/html; charset=UTF-8\n\n";
+
+print "<!DOCTYPE html>\n";
+print "<html>\n";
+print "<head>\n";
+print $cgi->param('q');
+print "<style src='dummy'>\n";
+print "</head>\n";
+print "<body>\n";
+print "<script src='safe-script.js'></script>\n";
+print "</body>\n";
+print "</html>\n";
diff --git a/LayoutTests/http/tests/security/xssAuditor/anchor-url-dom-write-location-expected.txt b/LayoutTests/http/tests/security/xssAuditor/script-tag-comment-HTML-entity-expected.txt
similarity index 100%
copy from LayoutTests/http/tests/security/xssAuditor/anchor-url-dom-write-location-expected.txt
copy to LayoutTests/http/tests/security/xssAuditor/script-tag-comment-HTML-entity-expected.txt
diff --git a/LayoutTests/http/tests/security/xssAuditor/script-tag-comment-HTML-entity.html b/LayoutTests/http/tests/security/xssAuditor/script-tag-comment-HTML-entity.html
new file mode 100644
index 0000000..f3fe61f
--- /dev/null
+++ b/LayoutTests/http/tests/security/xssAuditor/script-tag-comment-HTML-entity.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src="http://localhost:8000/security/xssAuditor/resources/echo-intertag.pl?q=<script>/*xx%26copy%3B*/alert(/XSS/)</script>">
+</iframe>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/xssAuditor/anchor-url-dom-write-location-expected.txt b/LayoutTests/http/tests/security/xssAuditor/script-tag-comment-expected.txt
similarity index 100%
copy from LayoutTests/http/tests/security/xssAuditor/anchor-url-dom-write-location-expected.txt
copy to LayoutTests/http/tests/security/xssAuditor/script-tag-comment-expected.txt
diff --git a/LayoutTests/http/tests/security/xssAuditor/script-tag-comment.html b/LayoutTests/http/tests/security/xssAuditor/script-tag-comment.html
new file mode 100644
index 0000000..0345b98
--- /dev/null
+++ b/LayoutTests/http/tests/security/xssAuditor/script-tag-comment.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src="http://localhost:8000/security/xssAuditor/resources/echo-before-image.pl?q=<script>alert(/XSS/);//">
+</iframe>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/xssAuditor/anchor-url-dom-write-location-expected.txt b/LayoutTests/http/tests/security/xssAuditor/script-tag-with-source-comment-expected.txt
similarity index 100%
copy from LayoutTests/http/tests/security/xssAuditor/anchor-url-dom-write-location-expected.txt
copy to LayoutTests/http/tests/security/xssAuditor/script-tag-with-source-comment-expected.txt
diff --git a/LayoutTests/http/tests/security/xssAuditor/script-tag-with-source-comment.html b/LayoutTests/http/tests/security/xssAuditor/script-tag-with-source-comment.html
new file mode 100644
index 0000000..97cbd1a
--- /dev/null
+++ b/LayoutTests/http/tests/security/xssAuditor/script-tag-with-source-comment.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.setXSSAuditorEnabled(true);
+}
+</script>
+</head>
+<body>
+<iframe src="http://localhost:8000/security/xssAuditor/resources/echo-before-image.pl?q=<script src=%22http://127.0.0.1:8000/security/xssAuditor/resources/xss.js?">
+</iframe>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 3c30504..8602ee8 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,34 @@
+2009-10-15  Daniel Bates  <dbates at webkit.org>
+
+        Reviewed by Adam Barth.
+
+        https://bugs.webkit.org/show_bug.cgi?id=27895
+        
+        Fixes an issue in which injecting an inline event handler whose value ends in a single-line
+        JavaScript comment can bypass the XSSAuditor. Similarly fixes this issue with respect to
+        the HTML Base element, HTML Object element, inline and external script tags, and
+        JavaScript multi-line variants of all of these attacks.
+
+        Tests: http/tests/security/xssAuditor/base-href-comment.html
+               http/tests/security/xssAuditor/iframe-javascript-url-comment.html
+               http/tests/security/xssAuditor/img-onerror-HTML-comment.html
+               http/tests/security/xssAuditor/img-onerror-comment.html
+               http/tests/security/xssAuditor/object-tag-comment.html
+               http/tests/security/xssAuditor/script-tag-comment-HTML-entity.html
+               http/tests/security/xssAuditor/script-tag-comment.html
+               http/tests/security/xssAuditor/script-tag-with-source-comment.html
+
+        * page/XSSAuditor.cpp: Added constant minAttackLength.
+        (WebCore::XSSAuditor::canEvaluate):
+        (WebCore::XSSAuditor::canEvaluateJavaScriptURL):
+        (WebCore::XSSAuditor::canCreateInlineEventListener):
+        (WebCore::XSSAuditor::canLoadExternalScriptFromSrc):
+        (WebCore::XSSAuditor::canLoadObject):
+        (WebCore::XSSAuditor::canSetBaseElementURL):
+        (WebCore::XSSAuditor::findInRequest): Added parameter context. Only looks at up 
+        to minAttackLength of script code plus context (if any).
+        * page/XSSAuditor.h:
+
 2009-10-08  Adam Langley  <agl at google.com>
 
         Reviewed by Eric Seidel.
diff --git a/WebCore/page/XSSAuditor.cpp b/WebCore/page/XSSAuditor.cpp
index 890c3fa..bcc3726 100644
--- a/WebCore/page/XSSAuditor.cpp
+++ b/WebCore/page/XSSAuditor.cpp
@@ -46,6 +46,11 @@ using namespace WTF;
 
 namespace WebCore {
 
+// Note, we believe it is sufficient to only look at a substring of 7
+// characters (or less) of code.  Observe that "alert()" is seven characters
+// in length.
+static const unsigned minAttackLength = 7;
+
 static bool isNonCanonicalCharacter(UChar c)
 {
     // We remove all non-ASCII characters, including non-printable ASCII characters.
@@ -105,7 +110,7 @@ bool XSSAuditor::canEvaluate(const String& code) const
     if (!isEnabled())
         return true;
 
-    if (findInRequest(code, false, true)) {
+    if (findInRequest(String(), code, false, true)) {
         DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n"));
         m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
         return false;
@@ -118,7 +123,7 @@ bool XSSAuditor::canEvaluateJavaScriptURL(const String& code) const
     if (!isEnabled())
         return true;
 
-    if (findInRequest(code, true, false, true)) {
+    if (findInRequest(String(), code, true, false, true)) {
         DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n"));
         m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
         return false;
@@ -131,7 +136,7 @@ bool XSSAuditor::canCreateInlineEventListener(const String&, const String& code)
     if (!isEnabled())
         return true;
 
-    if (findInRequest(code, true, true)) {
+    if (findInRequest(String(), code, true, true)) {
         DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n"));
         m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
         return false;
@@ -154,7 +159,7 @@ bool XSSAuditor::canLoadExternalScriptFromSrc(const String& context, const Strin
     if (m_frame->document()->url().host() == scriptURL.host() && scriptURL.query().isEmpty())
         return true;
 
-    if (findInRequest(context + url)) {
+    if (findInRequest(context, url)) {
         DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n"));
         m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
         return false;
@@ -167,7 +172,7 @@ bool XSSAuditor::canLoadObject(const String& url) const
     if (!isEnabled())
         return true;
 
-    if (findInRequest(url)) {
+    if (findInRequest(String(), url)) {
         DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request"));
         m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
         return false;
@@ -181,7 +186,7 @@ bool XSSAuditor::canSetBaseElementURL(const String& url) const
         return true;
     
     KURL baseElementURL(m_frame->document()->url(), url);
-    if (m_frame->document()->url().host() != baseElementURL.host() && findInRequest(url)) {
+    if (m_frame->document()->url().host() != baseElementURL.host() && findInRequest(String(), url)) {
         DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request"));
         m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
         return false;
@@ -255,19 +260,19 @@ String XSSAuditor::decodeHTMLEntities(const String& string, bool leaveUndecodabl
     return String::adopt(result);
 }
 
-bool XSSAuditor::findInRequest(const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters, 
+bool XSSAuditor::findInRequest(const String& context, const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters, 
                                bool decodeURLEscapeSequencesTwice) const
 {
     bool result = false;
     Frame* parentFrame = m_frame->tree()->parent();
     if (parentFrame && m_frame->document()->url() == blankURL())
-        result = findInRequest(parentFrame, string, decodeEntities, allowRequestIfNoIllegalURICharacters, decodeURLEscapeSequencesTwice);
+        result = findInRequest(parentFrame, context, string, decodeEntities, allowRequestIfNoIllegalURICharacters, decodeURLEscapeSequencesTwice);
     if (!result)
-        result = findInRequest(m_frame, string, decodeEntities, allowRequestIfNoIllegalURICharacters, decodeURLEscapeSequencesTwice);
+        result = findInRequest(m_frame, context, string, decodeEntities, allowRequestIfNoIllegalURICharacters, decodeURLEscapeSequencesTwice);
     return result;
 }
 
-bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters, 
+bool XSSAuditor::findInRequest(Frame* frame, const String& context, const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters, 
                                bool decodeURLEscapeSequencesTwice) const
 {
     ASSERT(frame->document());
@@ -281,13 +286,15 @@ bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEn
         return false;
 
     FormData* formDataObj = frame->loader()->documentLoader()->originalRequest().httpBody();
+    const bool hasFormData = formDataObj && !formDataObj->isEmpty();
     String pageURL = frame->document()->url().string();
-
-    if (!formDataObj && string.length() >= 2 * pageURL.length()) {
+    
+    String canonicalizedString;
+    if (!hasFormData && string.length() > 2 * pageURL.length()) {
         // Q: Why do we bother to do this check at all?
         // A: Canonicalizing large inline scripts can be expensive.  We want to
-        //    bail out before the call to canonicalize below, which could
-        //    result in an unneeded allocation and memcpy.
+        //    reduce the size of the string before we call canonicalize below, 
+        //    since it could result in an unneeded allocation and memcpy.
         //
         // Q: Why do we multiply by two here?
         // A: We attempt to detect reflected XSS even when the server
@@ -295,39 +302,37 @@ bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEn
         //    attacker can do get the server to inflate his/her input by a
         //    factor of two by sending " characters, which the server
         //    transforms to \".
-        return false;
-    }
+        canonicalizedString = string.substring(0, 2 * pageURL.length());
+    } else
+        canonicalizedString = string;
 
     if (frame->document()->url().protocolIs("data"))
         return false;
 
-    String canonicalizedString = canonicalize(string);
+    canonicalizedString = canonicalize(canonicalizedString);
     if (canonicalizedString.isEmpty())
         return false;
 
-    if (string.length() < pageURL.length()) {
-        // The string can actually fit inside the pageURL.
-        String decodedPageURL = m_cache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), decodeEntities, decodeURLEscapeSequencesTwice);
+    // We only look at the first minAttackLength characters to avoid looking at
+    // characters the attacker has pulled in from the page using an attack string
+    // like: <img onerror="alert(/XSS/);//
+    canonicalizedString = canonicalizedString.substring(0, minAttackLength);
 
-        if (allowRequestIfNoIllegalURICharacters && (!formDataObj || formDataObj->isEmpty()) 
-            && decodedPageURL.find(&isIllegalURICharacter, 0) == -1)
-            return false; // Injection is impossible because the request does not contain any illegal URI characters. 
+    if (!context.isEmpty())
+        canonicalizedString = context + canonicalizedString;
 
-        if (decodedPageURL.find(canonicalizedString, 0, false) != -1)
-            return true;  // We've found the smoking gun.
-    }
+    String decodedPageURL = m_cache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), decodeEntities, decodeURLEscapeSequencesTwice);
 
-    if (formDataObj && !formDataObj->isEmpty()) {
-        String formData = formDataObj->flattenToString();
-        if (string.length() < formData.length()) {
-            // Notice it is sufficient to compare the length of the string to
-            // the url-encoded POST data because the length of the url-decoded
-            // code is less than or equal to the length of the url-encoded
-            // string.
-            String decodedFormData = m_cache.canonicalizeURL(formData, frame->document()->decoder()->encoding(), decodeEntities, decodeURLEscapeSequencesTwice);
-            if (decodedFormData.find(canonicalizedString, 0, false) != -1)
-                return true;  // We found the string in the POST data.
-        }
+    if (allowRequestIfNoIllegalURICharacters && !hasFormData && decodedPageURL.find(&isIllegalURICharacter, 0) == -1)
+        return false; // Injection is impossible because the request does not contain any illegal URI characters. 
+
+    if (decodedPageURL.find(canonicalizedString, 0, false) != -1)
+        return true;  // We've found the string in the GET data.
+
+    if (hasFormData) {
+        String decodedFormData = m_cache.canonicalizeURL(formDataObj->flattenToString(), frame->document()->decoder()->encoding(), decodeEntities, decodeURLEscapeSequencesTwice);
+        if (decodedFormData.find(canonicalizedString, 0, false) != -1)
+            return true;  // We found the string in the POST data.
     }
 
     return false;
diff --git a/WebCore/page/XSSAuditor.h b/WebCore/page/XSSAuditor.h
index adfa5c7..de42720 100644
--- a/WebCore/page/XSSAuditor.h
+++ b/WebCore/page/XSSAuditor.h
@@ -122,9 +122,9 @@ namespace WebCore {
                                 bool decodeURLEscapeSequencesTwice = false);
         static String decodeHTMLEntities(const String&, bool leaveUndecodableEntitiesUntouched = true);
 
-        bool findInRequest(const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false, 
+        bool findInRequest(const String& context, const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false, 
                            bool decodeURLEscapeSequencesTwice = false) const;
-        bool findInRequest(Frame*, const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false, 
+        bool findInRequest(Frame*, const String& context, const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false, 
                            bool decodeURLEscapeSequencesTwice = false) const;
 
         // The frame to audit.

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list