Changeset 77058 in webkit


Ignore:
Timestamp:
Jan 29, 2011 1:19:21 AM (13 years ago)
Author:
abarth@webkit.org
Message:

2011-01-29 Adam Barth <abarth@webkit.org>

Reviewed by Daniel Bates.

XSSFilter should pass xssAuditor/script-tag-with-source-same-host.html
and xssAuditor/script-tag-post-*
https://bugs.webkit.org/show_bug.cgi?id=53364

We're supposed to allow loading same-origin resources even if they
appear as part of the request.

Also, we're supposed to look at the POST data too. :)

  • html/parser/XSSFilter.cpp: (WebCore::XSSFilter::eraseAttributeIfInjected): (WebCore::XSSFilter::isSameOriginResource):
    • Copy/paste from XSSAuditor::isSameOriginResource. We'll eventually remove the XSSAuditor version when XSSFilter is done.
  • html/parser/XSSFilter.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r77057 r77058  
     12011-01-29  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Daniel Bates.
     4
     5        XSSFilter should pass xssAuditor/script-tag-with-source-same-host.html
     6        and xssAuditor/script-tag-post-*
     7        https://bugs.webkit.org/show_bug.cgi?id=53364
     8
     9        We're supposed to allow loading same-origin resources even if they
     10        appear as part of the request.
     11
     12        Also, we're supposed to look at the POST data too.  :)
     13
     14        * html/parser/XSSFilter.cpp:
     15        (WebCore::XSSFilter::eraseAttributeIfInjected):
     16        (WebCore::XSSFilter::isSameOriginResource):
     17            - Copy/paste from XSSAuditor::isSameOriginResource.  We'll
     18              eventually remove the XSSAuditor version when XSSFilter is done.
     19        * html/parser/XSSFilter.h:
     20
    1212011-01-29  Adam Barth  <abarth@webkit.org>
    222
  • trunk/Source/WebCore/html/parser/XSSFilter.cpp

    r77057 r77058  
    2828
    2929#include "Document.h"
     30#include "DocumentLoader.h"
    3031#include "Frame.h"
    3132#include "HTMLDocumentParser.h"
     
    9495            m_isEnabled = settings->xssAuditorEnabled();
    9596    }
     97    // Although tempting to call init() at this point, the various objects
     98    // we want to reference might not all have been constructed yet.
     99}
     100
     101void XSSFilter::init()
     102{
     103    ASSERT(m_isEnabled);
     104
     105    const TextEncoding& encoding = m_parser->document()->decoder()->encoding();
     106    String url = m_parser->document()->url().string();
     107    m_decodedURL = decodeURL(url, encoding);
     108
     109    // In theory, the Document could have detached from the Frame after the
     110    // XSSFilter was constructed.
     111    if (!m_parser->document()->frame())
     112        return;
     113
     114    if (DocumentLoader* documentLoader = m_parser->document()->frame()->loader()->documentLoader()) {
     115        FormData* httpBody = documentLoader->originalRequest().httpBody();
     116        if (httpBody && !httpBody->isEmpty())
     117            m_decodedHTTPBody = decodeURL(httpBody->flattenToString(), encoding);
     118    }
    96119}
    97120
     
    104127    if (!m_isEnabled)
    105128        return;
     129
     130    if (m_decodedURL.isEmpty())
     131        init();
    106132
    107133    bool didBlockScript = false;
     
    270296        const HTMLToken::Attribute& attribute = token.attributes().at(indexOfAttribute);
    271297        if (isContainedInRequest(snippetForAttribute(token, attribute))) {
     298            if (attributeName == srcAttr && isSameOriginResource(String(attribute.m_value.data(), attribute.m_value.size())))
     299                return false;
    272300            token.eraseValueOfAttribute(indexOfAttribute);
    273301            if (!replacementValue.isEmpty())
     
    297325bool XSSFilter::isContainedInRequest(const String& snippet)
    298326{
    299     String url = m_parser->document()->url().string();
    300     String decodedURL = decodeURL(url, m_parser->document()->decoder()->encoding());
    301     if (decodedURL.find(snippet, 0, false) != notFound)
    302         return true; // We've found the string in the GET data.
    303     // FIXME: Look in form data.
    304     return false;
    305 }
    306 
    307 }
     327    return m_decodedURL.find(snippet, 0, false) != notFound || m_decodedHTTPBody.find(snippet, 0, false) != notFound;
     328}
     329
     330bool XSSFilter::isSameOriginResource(const String& url)
     331{
     332    // If the resource is loaded from the same URL as the enclosing page, it's
     333    // probably not an XSS attack, so we reduce false positives by allowing the
     334    // request. If the resource has a query string, we're more suspicious,
     335    // however, because that's pretty rare and the attacker might be able to
     336    // trick a server-side script into doing something dangerous with the query
     337    // string.
     338    KURL resourceURL(m_parser->document()->url(), url);
     339    return (m_parser->document()->url().host() == resourceURL.host() && resourceURL.query().isEmpty());
     340}
     341
     342}
  • trunk/Source/WebCore/html/parser/XSSFilter.h

    r77057 r77058  
    4646    };
    4747
     48    void init();
     49
    4850    bool filterTokenInitial(HTMLToken&);
    4951    bool filterTokenAfterScriptStartTag(HTMLToken&);
     
    6365
    6466    bool isContainedInRequest(const String&);
     67    bool isSameOriginResource(const String& url);
    6568
    6669    HTMLDocumentParser* m_parser;
    6770    bool m_isEnabled;
     71
     72    String m_decodedURL;
     73    String m_decodedHTTPBody;
     74
    6875    State m_state;
    6976    String m_cachedSnippet;
Note: See TracChangeset for help on using the changeset viewer.