Changeset 46250 in webkit


Ignore:
Timestamp:
Jul 22, 2009 4:27:19 PM (15 years ago)
Author:
abarth@webkit.org
Message:

2009-07-22 Daniel Bates <dbates@intudata.com>

Reviewed by Adam Barth.

https://bugs.webkit.org/show_bug.cgi?id=27174
And
https://bugs.webkit.org/show_bug.cgi?id=26938

Tests prevention of attacks transformed by PHP Magic Quotes/PHP addslashes().

  • http/tests/security/xssAuditor/resources/echo-intertag-addslashes.pl: Added.
  • http/tests/security/xssAuditor/script-tag-addslashes-backslash-expected.txt: Added.
  • http/tests/security/xssAuditor/script-tag-addslashes-backslash.html: Added.
  • http/tests/security/xssAuditor/script-tag-addslashes-double-quote-expected.txt: Added.
  • http/tests/security/xssAuditor/script-tag-addslashes-double-quote.html: Added.
  • http/tests/security/xssAuditor/script-tag-addslashes-null-char-expected.txt: Added.
  • http/tests/security/xssAuditor/script-tag-addslashes-null-char.html: Added.
  • http/tests/security/xssAuditor/script-tag-addslashes-single-quote-expected.txt: Added.
  • http/tests/security/xssAuditor/script-tag-addslashes-single-quote.html: Added.

2009-07-22 Daniel Bates <dbates@intudata.com>

Reviewed by Adam Barth.

https://bugs.webkit.org/show_bug.cgi?id=27174
And
https://bugs.webkit.org/show_bug.cgi?id=26938

Code cleanup. Implements support for detecting attacks transformed by
PHP Magic Quotes/PHP addslashes().

Tests: http/tests/security/xssAuditor/script-tag-addslashes-backslash.html

http/tests/security/xssAuditor/script-tag-addslashes-double-quote.html
http/tests/security/xssAuditor/script-tag-addslashes-null-char.html
http/tests/security/xssAuditor/script-tag-addslashes-single-quote.html

  • page/XSSAuditor.cpp: (WebCore::isInvalidCharacter): (WebCore::XSSAuditor::canEvaluate): (WebCore::XSSAuditor::canEvaluateJavaScriptURL): (WebCore::XSSAuditor::canLoadObject): (WebCore::XSSAuditor::normalize): Decodes HTML entities, removes backslashes, and removes control characters that could otherwise cause a discrepancy between the source code of a script and the outgoing HTTP parameters. (WebCore::XSSAuditor::decodeURL): (WebCore::XSSAuditor::decodeHTMLEntities): (WebCore::XSSAuditor::findInRequest):
  • page/XSSAuditor.h:
Location:
trunk
Files:
9 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r46240 r46250  
     12009-07-22  Daniel Bates  <dbates@intudata.com>
     2
     3        Reviewed by Adam Barth.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=27174
     6        And
     7        https://bugs.webkit.org/show_bug.cgi?id=26938
     8       
     9        Tests prevention of attacks transformed by PHP Magic Quotes/PHP addslashes().
     10
     11        * http/tests/security/xssAuditor/resources/echo-intertag-addslashes.pl: Added.
     12        * http/tests/security/xssAuditor/script-tag-addslashes-backslash-expected.txt: Added.
     13        * http/tests/security/xssAuditor/script-tag-addslashes-backslash.html: Added.
     14        * http/tests/security/xssAuditor/script-tag-addslashes-double-quote-expected.txt: Added.
     15        * http/tests/security/xssAuditor/script-tag-addslashes-double-quote.html: Added.
     16        * http/tests/security/xssAuditor/script-tag-addslashes-null-char-expected.txt: Added.
     17        * http/tests/security/xssAuditor/script-tag-addslashes-null-char.html: Added.
     18        * http/tests/security/xssAuditor/script-tag-addslashes-single-quote-expected.txt: Added.
     19        * http/tests/security/xssAuditor/script-tag-addslashes-single-quote.html: Added.
     20
    1212009-07-22  David Hyatt  <hyatt@apple.com>
    222
  • trunk/WebCore/ChangeLog

    r46246 r46250  
     12009-07-22  Daniel Bates  <dbates@intudata.com>
     2
     3        Reviewed by Adam Barth.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=27174
     6        And
     7        https://bugs.webkit.org/show_bug.cgi?id=26938
     8       
     9        Code cleanup. Implements support for detecting attacks transformed by
     10        PHP Magic Quotes/PHP addslashes().
     11
     12        Tests: http/tests/security/xssAuditor/script-tag-addslashes-backslash.html
     13               http/tests/security/xssAuditor/script-tag-addslashes-double-quote.html
     14               http/tests/security/xssAuditor/script-tag-addslashes-null-char.html
     15               http/tests/security/xssAuditor/script-tag-addslashes-single-quote.html
     16
     17        * page/XSSAuditor.cpp:
     18        (WebCore::isInvalidCharacter):
     19        (WebCore::XSSAuditor::canEvaluate):
     20        (WebCore::XSSAuditor::canEvaluateJavaScriptURL):
     21        (WebCore::XSSAuditor::canLoadObject):
     22        (WebCore::XSSAuditor::normalize): Decodes HTML entities, removes backslashes,
     23        and removes control characters that could otherwise cause a discrepancy between
     24        the source code of a script and the outgoing HTTP parameters.
     25        (WebCore::XSSAuditor::decodeURL):
     26        (WebCore::XSSAuditor::decodeHTMLEntities):
     27        (WebCore::XSSAuditor::findInRequest):
     28        * page/XSSAuditor.h:
     29
    1302009-07-22  Oliver Hunt  <oliver@apple.com>
    231
  • trunk/WebCore/page/XSSAuditor.cpp

    r46086 r46250  
    4747namespace WebCore {
    4848
    49 static bool isNonNullControlCharacter(UChar c)
    50 {
    51     return (c > '\0' && c < ' ') || c == 127;
     49static bool isNonCanonicalCharacter(UChar c)
     50{
     51    return (c == '\\' || c == '0' || c < ' ' || c == 127);
    5252}
    5353
     
    6767}
    6868
    69 bool XSSAuditor::canEvaluate(const String& sourceCode) const
    70 {
    71     if (!isEnabled())
    72         return true;
    73 
    74     if (findInRequest(sourceCode, false, true, false)) {
     69bool XSSAuditor::canEvaluate(const String& code) const
     70{
     71    if (!isEnabled())
     72        return true;
     73
     74    if (findInRequest(code, false)) {
    7575        DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n"));
    7676        m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
     
    8585        return true;
    8686
    87     if (findInRequest(code, false, false, true, true)) {
     87    if (findInRequest(code)) {
    8888        DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n"));
    8989        m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
     
    124124        return true;
    125125
    126     if (findInRequest(url, false, false)) {
     126    if (findInRequest(url)) {
    127127        DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request"));
    128128        m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
     
    146146}
    147147
    148 String XSSAuditor::decodeURL(const String& str, const TextEncoding& encoding, bool allowNullCharacters,
    149                              bool allowNonNullControlCharacters, bool decodeHTMLentities, bool leaveUndecodableHTMLEntitiesUntouched)
     148String XSSAuditor::canonicalize(const String& string)
     149{
     150    String result = decodeHTMLEntities(string);
     151    return result.removeCharacters(&isNonCanonicalCharacter);
     152}
     153
     154String XSSAuditor::decodeURL(const String& string, const TextEncoding& encoding, bool decodeHTMLentities)
    150155{
    151156    String result;
    152     String url = str;
     157    String url = string;
    153158
    154159    url.replace('+', ' ');
     
    158163        result = decodedResult;
    159164    if (decodeHTMLentities)
    160         result = decodeHTMLEntities(result, leaveUndecodableHTMLEntitiesUntouched);
    161     if (!allowNullCharacters)
    162         result = StringImpl::createStrippingNullCharacters(result.characters(), result.length());
    163     if (!allowNonNullControlCharacters) {
    164         decodedResult = result.removeCharacters(&isNonNullControlCharacter);
    165         if (!decodedResult.isEmpty())
    166             result = decodedResult;
    167     }
     165        result = decodeHTMLEntities(result);
    168166    return result;
    169167}
    170168
    171 String XSSAuditor::decodeHTMLEntities(const String& str, bool leaveUndecodableHTMLEntitiesUntouched)
    172 {
    173     SegmentedString source(str);
     169String XSSAuditor::decodeHTMLEntities(const String& string, bool leaveUndecodableHTMLEntitiesUntouched)
     170{
     171    SegmentedString source(string);
    174172    SegmentedString sourceShadow;
    175173    Vector<UChar> result;
     
    206204}
    207205
    208 bool XSSAuditor::findInRequest(const String& string, bool matchNullCharacters, bool matchNonNullControlCharacters,
    209                                bool decodeHTMLentities, bool leaveUndecodableHTMLEntitiesUntouched) const
     206bool XSSAuditor::findInRequest(const String& string, bool decodeHTMLentities) const
    210207{
    211208    bool result = false;
    212209    Frame* parentFrame = m_frame->tree()->parent();
    213210    if (parentFrame && m_frame->document()->url() == blankURL())
    214         result = findInRequest(parentFrame, string, matchNullCharacters, matchNonNullControlCharacters,
    215                                decodeHTMLentities, leaveUndecodableHTMLEntitiesUntouched);
     211        result = findInRequest(parentFrame, string, decodeHTMLentities);
    216212    if (!result)
    217         result = findInRequest(m_frame, string, matchNullCharacters, matchNonNullControlCharacters,
    218                                decodeHTMLentities, leaveUndecodableHTMLEntitiesUntouched);
     213        result = findInRequest(m_frame, string, decodeHTMLentities);
    219214    return result;
    220215}
    221216
    222 bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool matchNullCharacters, bool matchNonNullControlCharacters,
    223                                bool decodeHTMLentities, bool leaveUndecodableHTMLEntitiesUntouched) const
     217bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeHTMLentities) const
    224218{
    225219    ASSERT(frame->document());
     
    237231        return false;
    238232
     233    String canonicalizedString = canonicalize(string);
    239234    if (string.length() < pageURL.length()) {
    240235        // The string can actually fit inside the pageURL.
    241         String decodedPageURL = decodeURL(pageURL, frame->document()->decoder()->encoding(), matchNullCharacters,
    242                                           matchNonNullControlCharacters, decodeHTMLentities, leaveUndecodableHTMLEntitiesUntouched);
    243         if (decodedPageURL.find(string, 0, false) != -1)
     236        String decodedPageURL = canonicalize(decodeURL(pageURL, frame->document()->decoder()->encoding(), decodeHTMLentities));
     237        if (decodedPageURL.find(canonicalizedString, 0, false) != -1)
    244238           return true;  // We've found the smoking gun.
    245239    }
     
    253247            // code is less than or equal to the length of the url-encoded
    254248            // string.
    255             String decodedFormData = decodeURL(formData, frame->document()->decoder()->encoding(), matchNullCharacters,
    256                                                matchNonNullControlCharacters, decodeHTMLentities, leaveUndecodableHTMLEntitiesUntouched);
    257             if (decodedFormData.find(string, 0, false) != -1)
     249            String decodedFormData = canonicalize(decodeURL(formData, frame->document()->decoder()->encoding(), decodeHTMLentities));
     250            if (decodedFormData.find(canonicalizedString, 0, false) != -1)
    258251                return true;  // We found the string in the POST data.
    259252        }
  • trunk/WebCore/page/XSSAuditor.h

    r45787 r46250  
    7373        // Determines whether the script should be allowed or denied execution
    7474        // based on the content of any user-submitted data.
    75         bool canEvaluate(const String& sourceCode) const;
     75        bool canEvaluate(const String& code) const;
    7676
    7777        // Determines whether the JavaScript URL should be allowed or denied execution
     
    100100
    101101    private:
    102         static String decodeURL(const String& url, const TextEncoding& encoding = UTF8Encoding(), bool allowNullCharacters = false,
    103                                 bool allowNonNullControlCharacters = true, bool decodeHTMLentities = true,
    104                                 bool leaveUndecodableHTMLEntitiesUntouched = false);
     102        static String canonicalize(const String&);
    105103       
    106         static String decodeHTMLEntities(const String&, bool leaveUndecodableHTMLEntitiesUntouched = false);
     104        static String decodeURL(const String& url, const TextEncoding& encoding = UTF8Encoding(), bool decodeHTMLentities = true);
     105       
     106        static String decodeHTMLEntities(const String&, bool leaveUndecodableHTMLEntitiesUntouched = true);
    107107
    108         bool findInRequest(const String&, bool matchNullCharacters = true, bool matchNonNullControlCharacters = true,
    109                            bool decodeHTMLentities = true, bool leaveUndecodableHTMLEntitiesUntouched = false) const;
     108        bool findInRequest(const String&, bool decodeHTMLentities = true) const;
    110109
    111         bool findInRequest(Frame*, const String&, bool matchNullCharacters = true, bool matchNonNullControlCharacters = true,
    112                            bool decodeHTMLentities = true, bool leaveUndecodableHTMLEntitiesUntouched = false) const;
     110        bool findInRequest(Frame*, const String&, bool decodeHTMLentities = true) const;
    113111
    114112        // The frame to audit.
Note: See TracChangeset for help on using the changeset viewer.