Changeset 166202 in webkit


Ignore:
Timestamp:
Mar 24, 2014 4:11:43 PM (10 years ago)
Author:
dbates@webkit.org
Message:

XSS Auditor doesn't block <script> injected before an existing <script>
https://bugs.webkit.org/show_bug.cgi?id=130475

Merged from Blink (patch by Tom Sepez):
https://src.chromium.org/viewvc/blink?view=rev&revision=169697

Source/WebCore:

Tests: http/tests/security/xssAuditor/script-tag-expression-follows.html

http/tests/security/xssAuditor/script-tag-near-start.html

  • html/parser/XSSAuditor.cpp:

(WebCore::startsHTMLCommentAt):
(WebCore::startsSingleLineCommentAt):
(WebCore::startsMultiLineCommentAt):
(WebCore::startsOpeningScriptTagAt):
(WebCore::XSSAuditor::decodedSnippetForJavaScript):

LayoutTests:

  • http/tests/security/xssAuditor/resources/echo-intertag.pl:
  • http/tests/security/xssAuditor/script-tag-expression-follows-expected.txt: Added.
  • http/tests/security/xssAuditor/script-tag-expression-follows.html: Added.
  • http/tests/security/xssAuditor/script-tag-near-start-expected.txt: Added.
  • http/tests/security/xssAuditor/script-tag-near-start.html: Added.
Location:
trunk
Files:
4 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r166201 r166202  
     12014-03-24  Daniel Bates  <dabates@apple.com>
     2
     3        XSS Auditor doesn't block <script> injected before an existing <script>
     4        https://bugs.webkit.org/show_bug.cgi?id=130475
     5
     6        Merged from Blink (patch by Tom Sepez):
     7        https://src.chromium.org/viewvc/blink?view=rev&revision=169697
     8
     9        * http/tests/security/xssAuditor/resources/echo-intertag.pl:
     10        * http/tests/security/xssAuditor/script-tag-expression-follows-expected.txt: Added.
     11        * http/tests/security/xssAuditor/script-tag-expression-follows.html: Added.
     12        * http/tests/security/xssAuditor/script-tag-near-start-expected.txt: Added.
     13        * http/tests/security/xssAuditor/script-tag-near-start.html: Added.
     14
    1152014-03-24  Brent Fulgham  <bfulgham@apple.com>
    216
  • trunk/LayoutTests/http/tests/security/xssAuditor/resources/echo-intertag.pl

    r165986 r166202  
    9393    print "<script>history.replaceState({}, '', '#must-not-appear');</script>\n";
    9494}
    95 print $cgi->param('q');
     95print $cgi->param('q'); # XSS reflected here.
     96if ($cgi->param('script-expression-follows')) {
     97    print "\n <script>42;</script>\n";
     98}
    9699if ($cgi->param('clutter')) {
    97100    print $cgi->param('clutter');
  • trunk/Source/WebCore/ChangeLog

    r166201 r166202  
     12014-03-24  Daniel Bates  <dabates@apple.com>
     2
     3        XSS Auditor doesn't block <script> injected before an existing <script>
     4        https://bugs.webkit.org/show_bug.cgi?id=130475
     5
     6        Merged from Blink (patch by Tom Sepez):
     7        https://src.chromium.org/viewvc/blink?view=rev&revision=169697
     8
     9        Tests: http/tests/security/xssAuditor/script-tag-expression-follows.html
     10               http/tests/security/xssAuditor/script-tag-near-start.html
     11
     12        * html/parser/XSSAuditor.cpp:
     13        (WebCore::startsHTMLCommentAt):
     14        (WebCore::startsSingleLineCommentAt):
     15        (WebCore::startsMultiLineCommentAt):
     16        (WebCore::startsOpeningScriptTagAt):
     17        (WebCore::XSSAuditor::decodedSnippetForJavaScript):
     18
    1192014-03-24  Brent Fulgham  <bfulgham@apple.com>
    220
  • trunk/Source/WebCore/html/parser/XSSAuditor.cpp

    r165986 r166202  
    4242#include "TextResourceDecoder.h"
    4343#include "XLinkNames.h"
     44#include <wtf/ASCIICType.h>
    4445#include <wtf/MainThread.h>
    4546
     
    8889static bool startsHTMLCommentAt(const String& string, size_t start)
    8990{
    90     return (start + 3 < string.length() && string[start] == '<' && string[start+1] == '!' && string[start+2] == '-' && string[start+3] == '-');
     91    return (start + 3 < string.length() && string[start] == '<' && string[start + 1] == '!' && string[start + 2] == '-' && string[start + 3] == '-');
    9192}
    9293
    9394static bool startsSingleLineCommentAt(const String& string, size_t start)
    9495{
    95     return (start + 1 < string.length() && string[start] == '/' && string[start+1] == '/');
     96    return (start + 1 < string.length() && string[start] == '/' && string[start + 1] == '/');
    9697}
    9798
    9899static bool startsMultiLineCommentAt(const String& string, size_t start)
    99100{
    100     return (start + 1 < string.length() && string[start] == '/' && string[start+1] == '*');
     101    return (start + 1 < string.length() && string[start] == '/' && string[start + 1] == '*');
     102}
     103
     104static bool startsOpeningScriptTagAt(const String& string, size_t start)
     105{
     106    return start + 6 < string.length() && string[start] == '<'
     107        && WTF::toASCIILowerUnchecked(string[start + 1]) == 's'
     108        && WTF::toASCIILowerUnchecked(string[start + 2]) == 'c'
     109        && WTF::toASCIILowerUnchecked(string[start + 3]) == 'r'
     110        && WTF::toASCIILowerUnchecked(string[start + 4]) == 'i'
     111        && WTF::toASCIILowerUnchecked(string[start + 5]) == 'p'
     112        && WTF::toASCIILowerUnchecked(string[start + 6]) == 't';
    101113}
    102114
     
    622634    size_t endPosition = string.length();
    623635    size_t foundPosition = notFound;
     636    size_t lastNonSpacePosition = notFound;
    624637
    625638    // Skip over initial comments to find start of code.
     
    650663    String result;
    651664    while (startPosition < endPosition && !result.length()) {
    652         // Stop at next comment (using the same rules as above for SVG/XML vs HTML), when we
    653         // encounter a comma, or when we  exceed the maximum length target. The comma rule
    654         // covers a common parameter concatenation case performed by some webservers.
    655         // After hitting the length target, we can only stop at a point where we know we are
    656         // not in the middle of a %-escape sequence. For the sake of simplicity, approximate
    657         // not stopping inside a (possibly multiply encoded) %-esacpe sequence by breaking on
    658         // whitespace only. We should have enough text in these cases to avoid false positives.
     665        // Stop at next comment (using the same rules as above for SVG/XML vs HTML), when we encounter a comma,
     666        // when we hit an opening <script> tag, or when we exceed the maximum length target. The comma rule
     667        // covers a common parameter concatenation case performed by some web servers.
     668        lastNonSpacePosition = notFound;
    659669        for (foundPosition = startPosition; foundPosition < endPosition; foundPosition++) {
    660670            if (!request.shouldAllowCDATA) {
     
    668678                }
    669679            }
    670             if (string[foundPosition] == ',' || (foundPosition > startPosition + kMaximumFragmentLengthTarget && isHTMLSpace(string[foundPosition]))) {
     680            if (string[foundPosition] == ',')
     681                break;
     682
     683            if (lastNonSpacePosition != notFound && startsOpeningScriptTagAt(string, foundPosition)) {
     684                foundPosition = lastNonSpacePosition;
    671685                break;
    672686            }
     687
     688            if (foundPosition > startPosition + kMaximumFragmentLengthTarget) {
     689                // After hitting the length target, we can only stop at a point where we know we are
     690                // not in the middle of a %-escape sequence. For the sake of simplicity, approximate
     691                // not stopping inside a (possibly multiply encoded) %-escape sequence by breaking on
     692                // whitespace only. We should have enough text in these cases to avoid false positives.
     693                if (isHTMLSpace(string[foundPosition]))
     694                    break;
     695            }
     696
     697            if (!isHTMLSpace(string[foundPosition]))
     698                lastNonSpacePosition = foundPosition;
    673699        }
    674700
Note: See TracChangeset for help on using the changeset viewer.