Changeset 141897 in webkit


Ignore:
Timestamp:
Feb 5, 2013 9:55:51 AM (11 years ago)
Author:
tonyg@chromium.org
Message:

Continue making XSSAuditor thread safe: Remove dependency on parser's sourceForToken and TextResourceDecoder
https://bugs.webkit.org/show_bug.cgi?id=108698

Reviewed by Adam Barth.

We'd like to be able to call filterToken() from the BackgroundHTMLParser where there is no HTMLDocumentParser. So we are removing the dependencies of
filterToken() on the HTMLDocumentParser. This patch brings us one step closer to removing the m_parser member from XSSAuditor by passing in the
TextResourceDecoder and HTMLSourceTracker to filterToken. To keep the number of parameters from blowing up, this introduces a FilterTokenRequest struct
to hold its arguments. We expect to add one more member to this struct.

No new tests because no new functionality.

  • html/parser/HTMLDocumentParser.cpp:

(WebCore::HTMLDocumentParser::pumpTokenizer):

  • html/parser/HTMLDocumentParser.h:
  • html/parser/XSSAuditor.cpp:

(WebCore::XSSAuditor::filterToken):
(WebCore::XSSAuditor::filterStartToken):
(WebCore::XSSAuditor::filterCharacterToken):
(WebCore::XSSAuditor::filterScriptToken):
(WebCore::XSSAuditor::filterObjectToken):
(WebCore::XSSAuditor::filterParamToken):
(WebCore::XSSAuditor::filterEmbedToken):
(WebCore::XSSAuditor::filterAppletToken):
(WebCore::XSSAuditor::filterIframeToken):
(WebCore::XSSAuditor::filterMetaToken):
(WebCore::XSSAuditor::filterBaseToken):
(WebCore::XSSAuditor::filterFormToken):
(WebCore::XSSAuditor::eraseDangerousAttributesIfInjected):
(WebCore::XSSAuditor::eraseAttributeIfInjected):
(WebCore::XSSAuditor::decodedSnippetForName):
(WebCore::XSSAuditor::decodedSnippetForAttribute):
(WebCore::XSSAuditor::decodedSnippetForJavaScript):

  • html/parser/XSSAuditor.h:

(WebCore):
(WebCore::FilterTokenRequest::FilterTokenRequest):
(FilterTokenRequest):
(XSSAuditor):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r141892 r141897  
     12013-02-05  Tony Gentilcore  <tonyg@chromium.org>
     2
     3        Continue making XSSAuditor thread safe: Remove dependency on parser's sourceForToken and TextResourceDecoder
     4        https://bugs.webkit.org/show_bug.cgi?id=108698
     5
     6        Reviewed by Adam Barth.
     7
     8        We'd like to be able to call filterToken() from the BackgroundHTMLParser where there is no HTMLDocumentParser. So we are removing the dependencies of
     9        filterToken() on the HTMLDocumentParser. This patch brings us one step closer to removing the m_parser member from XSSAuditor by passing in the
     10        TextResourceDecoder and HTMLSourceTracker to filterToken. To keep the number of parameters from blowing up, this introduces a FilterTokenRequest struct
     11        to hold its arguments. We expect to add one more member to this struct.
     12
     13
     14        No new tests because no new functionality.
     15
     16        * html/parser/HTMLDocumentParser.cpp:
     17        (WebCore::HTMLDocumentParser::pumpTokenizer):
     18        * html/parser/HTMLDocumentParser.h:
     19        * html/parser/XSSAuditor.cpp:
     20        (WebCore::XSSAuditor::filterToken):
     21        (WebCore::XSSAuditor::filterStartToken):
     22        (WebCore::XSSAuditor::filterCharacterToken):
     23        (WebCore::XSSAuditor::filterScriptToken):
     24        (WebCore::XSSAuditor::filterObjectToken):
     25        (WebCore::XSSAuditor::filterParamToken):
     26        (WebCore::XSSAuditor::filterEmbedToken):
     27        (WebCore::XSSAuditor::filterAppletToken):
     28        (WebCore::XSSAuditor::filterIframeToken):
     29        (WebCore::XSSAuditor::filterMetaToken):
     30        (WebCore::XSSAuditor::filterBaseToken):
     31        (WebCore::XSSAuditor::filterFormToken):
     32        (WebCore::XSSAuditor::eraseDangerousAttributesIfInjected):
     33        (WebCore::XSSAuditor::eraseAttributeIfInjected):
     34        (WebCore::XSSAuditor::decodedSnippetForName):
     35        (WebCore::XSSAuditor::decodedSnippetForAttribute):
     36        (WebCore::XSSAuditor::decodedSnippetForJavaScript):
     37        * html/parser/XSSAuditor.h:
     38        (WebCore):
     39        (WebCore::FilterTokenRequest::FilterTokenRequest):
     40        (FilterTokenRequest):
     41        (XSSAuditor):
     42
    1432013-02-05  Jocelyn Turcotte  <jocelyn.turcotte@digia.com>
    244
  • trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp

    r141605 r141897  
    379379            // We do not XSS filter innerHTML, which means we (intentionally) fail
    380380            // http/tests/security/xssAuditor/dom-write-innerHTML.html
    381             OwnPtr<DidBlockScriptRequest> request = m_xssAuditor.filterToken(token());
     381            OwnPtr<DidBlockScriptRequest> request = m_xssAuditor.filterToken(FilterTokenRequest(token(), m_sourceTracker, document()->decoder()));
    382382            if (request)
    383383                m_xssAuditorDelegate.didBlockScript(request.release());
     
    666666}
    667667
    668 String HTMLDocumentParser::sourceForToken(const HTMLToken& token)
    669 {
    670     return m_sourceTracker.sourceForToken(token);
    671 }
    672 
    673668OrdinalNumber HTMLDocumentParser::lineNumber() const
    674669{
  • trunk/Source/WebCore/html/parser/HTMLDocumentParser.h

    r141494 r141897  
    7676
    7777    HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); }
    78     String sourceForToken(const HTMLToken&);
    7978
    8079    virtual TextPosition textPosition() const;
  • trunk/Source/WebCore/html/parser/XSSAuditor.cpp

    r141791 r141897  
    279279}
    280280
    281 PassOwnPtr<DidBlockScriptRequest> XSSAuditor::filterToken(HTMLToken& token)
     281PassOwnPtr<DidBlockScriptRequest> XSSAuditor::filterToken(const FilterTokenRequest& request)
    282282{
    283283    ASSERT(m_state == Initialized);
     
    286286
    287287    bool didBlockScript = false;
    288     if (token.type() == HTMLTokenTypes::StartTag)
    289         didBlockScript = filterStartToken(token);
     288    if (request.token.type() == HTMLTokenTypes::StartTag)
     289        didBlockScript = filterStartToken(request);
    290290    else if (m_scriptTagNestingLevel) {
    291         if (token.type() == HTMLTokenTypes::Character)
    292             didBlockScript = filterCharacterToken(token);
    293         else if (token.type() == HTMLTokenTypes::EndTag)
    294             filterEndToken(token);
     291        if (request.token.type() == HTMLTokenTypes::Character)
     292            didBlockScript = filterCharacterToken(request);
     293        else if (request.token.type() == HTMLTokenTypes::EndTag)
     294            filterEndToken(request.token);
    295295    }
    296296
    297297    if (didBlockScript) {
    298298        bool didBlockEntirePage = (m_xssProtection == XSSProtectionBlockEnabled);
    299         OwnPtr<DidBlockScriptRequest> request = DidBlockScriptRequest::create(m_reportURL, m_originalURL, m_originalHTTPBody, didBlockEntirePage);
     299        OwnPtr<DidBlockScriptRequest> didBlockScriptRequest = DidBlockScriptRequest::create(m_reportURL, m_originalURL, m_originalHTTPBody, didBlockEntirePage);
    300300        if (!m_reportURL.isEmpty()) {
    301301            m_reportURL = KURL();
     
    303303            m_originalHTTPBody = String();
    304304        }
    305         return request.release();
     305        return didBlockScriptRequest.release();
    306306    }
    307307    return nullptr;
    308308}
    309309
    310 bool XSSAuditor::filterStartToken(HTMLToken& token)
    311 {
    312     bool didBlockScript = eraseDangerousAttributesIfInjected(token);
    313 
    314     if (hasName(token, scriptTag)) {
    315         didBlockScript |= filterScriptToken(token);
     310bool XSSAuditor::filterStartToken(const FilterTokenRequest& request)
     311{
     312    bool didBlockScript = eraseDangerousAttributesIfInjected(request);
     313
     314    if (hasName(request.token, scriptTag)) {
     315        didBlockScript |= filterScriptToken(request);
    316316        ASSERT(m_shouldAllowCDATA || !m_scriptTagNestingLevel);
    317317        m_scriptTagNestingLevel++;
    318     } else if (hasName(token, objectTag))
    319         didBlockScript |= filterObjectToken(token);
    320     else if (hasName(token, paramTag))
    321         didBlockScript |= filterParamToken(token);
    322     else if (hasName(token, embedTag))
    323         didBlockScript |= filterEmbedToken(token);
    324     else if (hasName(token, appletTag))
    325         didBlockScript |= filterAppletToken(token);
    326     else if (hasName(token, iframeTag))
    327         didBlockScript |= filterIframeToken(token);
    328     else if (hasName(token, metaTag))
    329         didBlockScript |= filterMetaToken(token);
    330     else if (hasName(token, baseTag))
    331         didBlockScript |= filterBaseToken(token);
    332     else if (hasName(token, formTag))
    333         didBlockScript |= filterFormToken(token);
     318    } else if (hasName(request.token, objectTag))
     319        didBlockScript |= filterObjectToken(request);
     320    else if (hasName(request.token, paramTag))
     321        didBlockScript |= filterParamToken(request);
     322    else if (hasName(request.token, embedTag))
     323        didBlockScript |= filterEmbedToken(request);
     324    else if (hasName(request.token, appletTag))
     325        didBlockScript |= filterAppletToken(request);
     326    else if (hasName(request.token, iframeTag))
     327        didBlockScript |= filterIframeToken(request);
     328    else if (hasName(request.token, metaTag))
     329        didBlockScript |= filterMetaToken(request);
     330    else if (hasName(request.token, baseTag))
     331        didBlockScript |= filterBaseToken(request);
     332    else if (hasName(request.token, formTag))
     333        didBlockScript |= filterFormToken(request);
    334334
    335335    return didBlockScript;
     
    345345}
    346346
    347 bool XSSAuditor::filterCharacterToken(HTMLToken& token)
     347bool XSSAuditor::filterCharacterToken(const FilterTokenRequest& request)
    348348{
    349349    ASSERT(m_scriptTagNestingLevel);
    350     if (isContainedInRequest(m_cachedDecodedSnippet) && isContainedInRequest(decodedSnippetForJavaScript(token))) {
    351         token.eraseCharacters();
    352         token.appendToCharacter(' '); // Technically, character tokens can't be empty.
     350    if (isContainedInRequest(m_cachedDecodedSnippet) && isContainedInRequest(decodedSnippetForJavaScript(request))) {
     351        request.token.eraseCharacters();
     352        request.token.appendToCharacter(' '); // Technically, character tokens can't be empty.
    353353        return true;
    354354    }
     
    356356}
    357357
    358 bool XSSAuditor::filterScriptToken(HTMLToken& token)
    359 {
    360     ASSERT(token.type() == HTMLTokenTypes::StartTag);
    361     ASSERT(hasName(token, scriptTag));
    362 
    363     m_cachedDecodedSnippet = decodedSnippetForName(token);
     358bool XSSAuditor::filterScriptToken(const FilterTokenRequest& request)
     359{
     360    ASSERT(request.token.type() == HTMLTokenTypes::StartTag);
     361    ASSERT(hasName(request.token, scriptTag));
     362
     363    m_cachedDecodedSnippet = decodedSnippetForName(request);
    364364    m_shouldAllowCDATA = m_parser->tokenizer()->shouldAllowCDATA();
    365365
    366366    bool didBlockScript = false;
    367     if (isContainedInRequest(decodedSnippetForName(token))) {
    368         didBlockScript |= eraseAttributeIfInjected(token, srcAttr, blankURL().string(), SrcLikeAttribute);
    369         didBlockScript |= eraseAttributeIfInjected(token, XLinkNames::hrefAttr, blankURL().string(), SrcLikeAttribute);
     367    if (isContainedInRequest(decodedSnippetForName(request))) {
     368        didBlockScript |= eraseAttributeIfInjected(request, srcAttr, blankURL().string(), SrcLikeAttribute);
     369        didBlockScript |= eraseAttributeIfInjected(request, XLinkNames::hrefAttr, blankURL().string(), SrcLikeAttribute);
    370370    }
    371371
     
    373373}
    374374
    375 bool XSSAuditor::filterObjectToken(HTMLToken& token)
    376 {
    377     ASSERT(token.type() == HTMLTokenTypes::StartTag);
    378     ASSERT(hasName(token, objectTag));
     375bool XSSAuditor::filterObjectToken(const FilterTokenRequest& request)
     376{
     377    ASSERT(request.token.type() == HTMLTokenTypes::StartTag);
     378    ASSERT(hasName(request.token, objectTag));
    379379
    380380    bool didBlockScript = false;
    381     if (isContainedInRequest(decodedSnippetForName(token))) {
    382         didBlockScript |= eraseAttributeIfInjected(token, dataAttr, blankURL().string(), SrcLikeAttribute);
    383         didBlockScript |= eraseAttributeIfInjected(token, typeAttr);
    384         didBlockScript |= eraseAttributeIfInjected(token, classidAttr);
     381    if (isContainedInRequest(decodedSnippetForName(request))) {
     382        didBlockScript |= eraseAttributeIfInjected(request, dataAttr, blankURL().string(), SrcLikeAttribute);
     383        didBlockScript |= eraseAttributeIfInjected(request, typeAttr);
     384        didBlockScript |= eraseAttributeIfInjected(request, classidAttr);
    385385    }
    386386    return didBlockScript;
    387387}
    388388
    389 bool XSSAuditor::filterParamToken(HTMLToken& token)
    390 {
    391     ASSERT(token.type() == HTMLTokenTypes::StartTag);
    392     ASSERT(hasName(token, paramTag));
     389bool XSSAuditor::filterParamToken(const FilterTokenRequest& request)
     390{
     391    ASSERT(request.token.type() == HTMLTokenTypes::StartTag);
     392    ASSERT(hasName(request.token, paramTag));
    393393
    394394    size_t indexOfNameAttribute;
    395     if (!findAttributeWithName(token, nameAttr, indexOfNameAttribute))
     395    if (!findAttributeWithName(request.token, nameAttr, indexOfNameAttribute))
    396396        return false;
    397397
    398     const HTMLToken::Attribute& nameAttribute = token.attributes().at(indexOfNameAttribute);
     398    const HTMLToken::Attribute& nameAttribute = request.token.attributes().at(indexOfNameAttribute);
    399399    String name = String(nameAttribute.m_value.data(), nameAttribute.m_value.size());
    400400
     
    402402        return false;
    403403
    404     return eraseAttributeIfInjected(token, valueAttr, blankURL().string(), SrcLikeAttribute);
    405 }
    406 
    407 bool XSSAuditor::filterEmbedToken(HTMLToken& token)
    408 {
    409     ASSERT(token.type() == HTMLTokenTypes::StartTag);
    410     ASSERT(hasName(token, embedTag));
     404    return eraseAttributeIfInjected(request, valueAttr, blankURL().string(), SrcLikeAttribute);
     405}
     406
     407bool XSSAuditor::filterEmbedToken(const FilterTokenRequest& request)
     408{
     409    ASSERT(request.token.type() == HTMLTokenTypes::StartTag);
     410    ASSERT(hasName(request.token, embedTag));
    411411
    412412    bool didBlockScript = false;
    413     if (isContainedInRequest(decodedSnippetForName(token))) {
    414         didBlockScript |= eraseAttributeIfInjected(token, codeAttr, String(), SrcLikeAttribute);
    415         didBlockScript |= eraseAttributeIfInjected(token, srcAttr, blankURL().string(), SrcLikeAttribute);
    416         didBlockScript |= eraseAttributeIfInjected(token, typeAttr);
     413    if (isContainedInRequest(decodedSnippetForName(request))) {
     414        didBlockScript |= eraseAttributeIfInjected(request, codeAttr, String(), SrcLikeAttribute);
     415        didBlockScript |= eraseAttributeIfInjected(request, srcAttr, blankURL().string(), SrcLikeAttribute);
     416        didBlockScript |= eraseAttributeIfInjected(request, typeAttr);
    417417    }
    418418    return didBlockScript;
    419419}
    420420
    421 bool XSSAuditor::filterAppletToken(HTMLToken& token)
    422 {
    423     ASSERT(token.type() == HTMLTokenTypes::StartTag);
    424     ASSERT(hasName(token, appletTag));
     421bool XSSAuditor::filterAppletToken(const FilterTokenRequest& request)
     422{
     423    ASSERT(request.token.type() == HTMLTokenTypes::StartTag);
     424    ASSERT(hasName(request.token, appletTag));
    425425
    426426    bool didBlockScript = false;
    427     if (isContainedInRequest(decodedSnippetForName(token))) {
    428         didBlockScript |= eraseAttributeIfInjected(token, codeAttr, String(), SrcLikeAttribute);
    429         didBlockScript |= eraseAttributeIfInjected(token, objectAttr);
     427    if (isContainedInRequest(decodedSnippetForName(request))) {
     428        didBlockScript |= eraseAttributeIfInjected(request, codeAttr, String(), SrcLikeAttribute);
     429        didBlockScript |= eraseAttributeIfInjected(request, objectAttr);
    430430    }
    431431    return didBlockScript;
    432432}
    433433
    434 bool XSSAuditor::filterIframeToken(HTMLToken& token)
    435 {
    436     ASSERT(token.type() == HTMLTokenTypes::StartTag);
    437     ASSERT(hasName(token, iframeTag));
     434bool XSSAuditor::filterIframeToken(const FilterTokenRequest& request)
     435{
     436    ASSERT(request.token.type() == HTMLTokenTypes::StartTag);
     437    ASSERT(hasName(request.token, iframeTag));
    438438
    439439    bool didBlockScript = false;
    440     if (isContainedInRequest(decodedSnippetForName(token))) {
    441         didBlockScript |= eraseAttributeIfInjected(token, srcAttr, String(), SrcLikeAttribute);
    442         didBlockScript |= eraseAttributeIfInjected(token, srcdocAttr, String(), ScriptLikeAttribute);
     440    if (isContainedInRequest(decodedSnippetForName(request))) {
     441        didBlockScript |= eraseAttributeIfInjected(request, srcAttr, String(), SrcLikeAttribute);
     442        didBlockScript |= eraseAttributeIfInjected(request, srcdocAttr, String(), ScriptLikeAttribute);
    443443    }
    444444    return didBlockScript;
    445445}
    446446
    447 bool XSSAuditor::filterMetaToken(HTMLToken& token)
    448 {
    449     ASSERT(token.type() == HTMLTokenTypes::StartTag);
    450     ASSERT(hasName(token, metaTag));
    451 
    452     return eraseAttributeIfInjected(token, http_equivAttr);
    453 }
    454 
    455 bool XSSAuditor::filterBaseToken(HTMLToken& token)
    456 {
    457     ASSERT(token.type() == HTMLTokenTypes::StartTag);
    458     ASSERT(hasName(token, baseTag));
    459 
    460     return eraseAttributeIfInjected(token, hrefAttr);
    461 }
    462 
    463 bool XSSAuditor::filterFormToken(HTMLToken& token)
    464 {
    465     ASSERT(token.type() == HTMLTokenTypes::StartTag);
    466     ASSERT(hasName(token, formTag));
    467 
    468     return eraseAttributeIfInjected(token, actionAttr, blankURL().string());
    469 }
    470 
    471 bool XSSAuditor::eraseDangerousAttributesIfInjected(HTMLToken& token)
     447bool XSSAuditor::filterMetaToken(const FilterTokenRequest& request)
     448{
     449    ASSERT(request.token.type() == HTMLTokenTypes::StartTag);
     450    ASSERT(hasName(request.token, metaTag));
     451
     452    return eraseAttributeIfInjected(request, http_equivAttr);
     453}
     454
     455bool XSSAuditor::filterBaseToken(const FilterTokenRequest& request)
     456{
     457    ASSERT(request.token.type() == HTMLTokenTypes::StartTag);
     458    ASSERT(hasName(request.token, baseTag));
     459
     460    return eraseAttributeIfInjected(request, hrefAttr);
     461}
     462
     463bool XSSAuditor::filterFormToken(const FilterTokenRequest& request)
     464{
     465    ASSERT(request.token.type() == HTMLTokenTypes::StartTag);
     466    ASSERT(hasName(request.token, formTag));
     467
     468    return eraseAttributeIfInjected(request, actionAttr, blankURL().string());
     469}
     470
     471bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& request)
    472472{
    473473    DEFINE_STATIC_LOCAL(String, safeJavaScriptURL, (ASCIILiteral("javascript:void(0)")));
    474474
    475475    bool didBlockScript = false;
    476     for (size_t i = 0; i < token.attributes().size(); ++i) {
    477         const HTMLToken::Attribute& attribute = token.attributes().at(i);
     476    for (size_t i = 0; i < request.token.attributes().size(); ++i) {
     477        const HTMLToken::Attribute& attribute = request.token.attributes().at(i);
    478478        bool isInlineEventHandler = isNameOfInlineEventHandler(attribute.m_name);
    479479        bool valueContainsJavaScriptURL = !isInlineEventHandler && protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(String(attribute.m_value.data(), attribute.m_value.size())));
    480480        if (!isInlineEventHandler && !valueContainsJavaScriptURL)
    481481            continue;
    482         if (!isContainedInRequest(decodedSnippetForAttribute(token, attribute, ScriptLikeAttribute)))
     482        if (!isContainedInRequest(decodedSnippetForAttribute(request, attribute, ScriptLikeAttribute)))
    483483            continue;
    484         token.eraseValueOfAttribute(i);
     484        request.token.eraseValueOfAttribute(i);
    485485        if (valueContainsJavaScriptURL)
    486             token.appendToAttributeValue(i, safeJavaScriptURL);
     486            request.token.appendToAttributeValue(i, safeJavaScriptURL);
    487487        didBlockScript = true;
    488488    }
     
    490490}
    491491
    492 bool XSSAuditor::eraseAttributeIfInjected(HTMLToken& token, const QualifiedName& attributeName, const String& replacementValue, AttributeKind treatment)
     492bool XSSAuditor::eraseAttributeIfInjected(const FilterTokenRequest& request, const QualifiedName& attributeName, const String& replacementValue, AttributeKind treatment)
    493493{
    494494    size_t indexOfAttribute = 0;
    495     if (findAttributeWithName(token, attributeName, indexOfAttribute)) {
    496         const HTMLToken::Attribute& attribute = token.attributes().at(indexOfAttribute);
    497         if (isContainedInRequest(decodedSnippetForAttribute(token, attribute, treatment))) {
     495    if (findAttributeWithName(request.token, attributeName, indexOfAttribute)) {
     496        const HTMLToken::Attribute& attribute = request.token.attributes().at(indexOfAttribute);
     497        if (isContainedInRequest(decodedSnippetForAttribute(request, attribute, treatment))) {
    498498            if (threadSafeMatch(attributeName, srcAttr) && isLikelySafeResource(String(attribute.m_value.data(), attribute.m_value.size())))
    499499                return false;
    500500            if (threadSafeMatch(attributeName, http_equivAttr) && !isDangerousHTTPEquiv(String(attribute.m_value.data(), attribute.m_value.size())))
    501501                return false;
    502             token.eraseValueOfAttribute(indexOfAttribute);
     502            request.token.eraseValueOfAttribute(indexOfAttribute);
    503503            if (!replacementValue.isEmpty())
    504                 token.appendToAttributeValue(indexOfAttribute, replacementValue);
     504                request.token.appendToAttributeValue(indexOfAttribute, replacementValue);
    505505            return true;
    506506        }
     
    509509}
    510510
    511 String XSSAuditor::decodedSnippetForName(const HTMLToken& token)
     511String XSSAuditor::decodedSnippetForName(const FilterTokenRequest& request)
    512512{
    513513    // Grab a fixed number of characters equal to the length of the token's name plus one (to account for the "<").
    514     return fullyDecodeString(m_parser->sourceForToken(token), m_parser->document()->decoder()).substring(0, token.name().size() + 1);
    515 }
    516 
    517 String XSSAuditor::decodedSnippetForAttribute(const HTMLToken& token, const HTMLToken::Attribute& attribute, AttributeKind treatment)
     514    return fullyDecodeString(request.sourceTracker.sourceForToken(request.token), request.decoder).substring(0, request.token.name().size() + 1);
     515}
     516
     517String XSSAuditor::decodedSnippetForAttribute(const FilterTokenRequest& request, const HTMLToken::Attribute& attribute, AttributeKind treatment)
    518518{
    519519    // The range doesn't inlcude the character which terminates the value. So,
     
    521521    // unquoted input of |name=value |, the snippet is |name=value|.
    522522    // FIXME: We should grab one character before the name also.
    523     int start = attribute.m_nameRange.m_start - token.startIndex();
    524     int end = attribute.m_valueRange.m_end - token.startIndex();
    525     String decodedSnippet = fullyDecodeString(m_parser->sourceForToken(token).substring(start, end - start), m_parser->document()->decoder());
     523    int start = attribute.m_nameRange.m_start - request.token.startIndex();
     524    int end = attribute.m_valueRange.m_end - request.token.startIndex();
     525    String decodedSnippet = fullyDecodeString(request.sourceTracker.sourceForToken(request.token).substring(start, end - start), request.decoder);
    526526    decodedSnippet.truncate(kMaximumFragmentLengthTarget);
    527527    if (treatment == SrcLikeAttribute) {
     
    574574}
    575575
    576 String XSSAuditor::decodedSnippetForJavaScript(const HTMLToken& token)
    577 {
    578     String string = m_parser->sourceForToken(token);
     576String XSSAuditor::decodedSnippetForJavaScript(const FilterTokenRequest& request)
     577{
     578    String string = request.sourceTracker.sourceForToken(request.token);
    579579    size_t startPosition = 0;
    580580    size_t endPosition = string.length();
     
    631631        }
    632632
    633         result = fullyDecodeString(string.substring(startPosition, foundPosition - startPosition), m_parser->document()->decoder());
     633        result = fullyDecodeString(string.substring(startPosition, foundPosition - startPosition), request.decoder);
    634634        startPosition = foundPosition + 1;
    635635    }
  • trunk/Source/WebCore/html/parser/XSSAuditor.h

    r141633 r141897  
    3737class Document;
    3838class HTMLDocumentParser;
     39class HTMLSourceTracker;
     40class TextResourceDecoder;
     41
     42struct FilterTokenRequest {
     43    FilterTokenRequest(HTMLToken& token, HTMLSourceTracker& sourceTracker, const TextResourceDecoder* decoder)
     44        : token(token)
     45        , sourceTracker(sourceTracker)
     46        , decoder(decoder)
     47    { }
     48
     49    HTMLToken& token;
     50    HTMLSourceTracker& sourceTracker;
     51    const TextResourceDecoder* decoder;
     52};
    3953
    4054class XSSAuditor {
     
    4458
    4559    void init(Document*);
    46     PassOwnPtr<DidBlockScriptRequest> filterToken(HTMLToken&);
     60    PassOwnPtr<DidBlockScriptRequest> filterToken(const FilterTokenRequest&);
    4761
    4862private:
     
    6074    };
    6175
    62     bool filterStartToken(HTMLToken&);
     76    bool filterStartToken(const FilterTokenRequest&);
    6377    void filterEndToken(HTMLToken&);
    64     bool filterCharacterToken(HTMLToken&);
    65     bool filterScriptToken(HTMLToken&);
    66     bool filterObjectToken(HTMLToken&);
    67     bool filterParamToken(HTMLToken&);
    68     bool filterEmbedToken(HTMLToken&);
    69     bool filterAppletToken(HTMLToken&);
    70     bool filterIframeToken(HTMLToken&);
    71     bool filterMetaToken(HTMLToken&);
    72     bool filterBaseToken(HTMLToken&);
    73     bool filterFormToken(HTMLToken&);
     78    bool filterCharacterToken(const FilterTokenRequest&);
     79    bool filterScriptToken(const FilterTokenRequest&);
     80    bool filterObjectToken(const FilterTokenRequest&);
     81    bool filterParamToken(const FilterTokenRequest&);
     82    bool filterEmbedToken(const FilterTokenRequest&);
     83    bool filterAppletToken(const FilterTokenRequest&);
     84    bool filterIframeToken(const FilterTokenRequest&);
     85    bool filterMetaToken(const FilterTokenRequest&);
     86    bool filterBaseToken(const FilterTokenRequest&);
     87    bool filterFormToken(const FilterTokenRequest&);
    7488
    75     bool eraseDangerousAttributesIfInjected(HTMLToken&);
    76     bool eraseAttributeIfInjected(HTMLToken&, const QualifiedName&, const String& replacementValue = String(), AttributeKind treatment = NormalAttribute);
     89    bool eraseDangerousAttributesIfInjected(const FilterTokenRequest&);
     90    bool eraseAttributeIfInjected(const FilterTokenRequest&, const QualifiedName&, const String& replacementValue = String(), AttributeKind treatment = NormalAttribute);
    7791
    7892    String decodedSnippetForToken(const HTMLToken&);
    79     String decodedSnippetForName(const HTMLToken&);
    80     String decodedSnippetForAttribute(const HTMLToken&, const HTMLToken::Attribute&, AttributeKind treatment = NormalAttribute);
    81     String decodedSnippetForJavaScript(const HTMLToken&);
     93    String decodedSnippetForName(const FilterTokenRequest&);
     94    String decodedSnippetForAttribute(const FilterTokenRequest&, const HTMLToken::Attribute&, AttributeKind treatment = NormalAttribute);
     95    String decodedSnippetForJavaScript(const FilterTokenRequest&);
    8296
    8397    bool isContainedInRequest(const String&);
Note: See TracChangeset for help on using the changeset viewer.