[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198

abarth at webkit.org abarth at webkit.org
Mon Feb 21 00:16:26 UTC 2011


The following commit has been merged in the webkit-1.3 branch:
commit bfc7fcf58835d9363074c36246c83e859992baa7
Author: abarth at webkit.org <abarth at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sat Jan 29 02:08:44 2011 +0000

    2011-01-28  Adam Barth  <abarth at webkit.org>
    
            Reviewed by Eric Seidel.
    
            XSSFilter should log to the console when it blocks something
            https://bugs.webkit.org/show_bug.cgi?id=53354
    
            This patch refactors a bunch of methods in XSSFilter to return a bool
            indicating whether they blocked anything.  Using this bool, we decide
            whether to log to the console.  We're using the same log message as the
            XSSAuditor, but it seems likely we can improve this message in the
            future (especially by piping in the correct line number, which is now
            accessible via the parser).
    
            * html/parser/XSSFilter.cpp:
            (WebCore::HTMLNames::isNameOfInlineEventHandler):
            (WebCore::XSSFilter::filterToken):
            (WebCore::XSSFilter::filterTokenInitial):
            (WebCore::XSSFilter::filterTokenAfterScriptStartTag):
            (WebCore::XSSFilter::filterScriptToken):
            (WebCore::XSSFilter::filterObjectToken):
            (WebCore::XSSFilter::filterEmbedToken):
            (WebCore::XSSFilter::filterAppletToken):
            (WebCore::XSSFilter::filterMetaToken):
            (WebCore::XSSFilter::filterBaseToken):
            (WebCore::XSSFilter::eraseInlineEventHandlersIfInjected):
            * html/parser/XSSFilter.h:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@77041 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 07a9d83..14dc5fe 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,5 +1,33 @@
 2011-01-28  Adam Barth  <abarth at webkit.org>
 
+        Reviewed by Eric Seidel.
+
+        XSSFilter should log to the console when it blocks something
+        https://bugs.webkit.org/show_bug.cgi?id=53354
+
+        This patch refactors a bunch of methods in XSSFilter to return a bool
+        indicating whether they blocked anything.  Using this bool, we decide
+        whether to log to the console.  We're using the same log message as the
+        XSSAuditor, but it seems likely we can improve this message in the
+        future (especially by piping in the correct line number, which is now
+        accessible via the parser).
+
+        * html/parser/XSSFilter.cpp:
+        (WebCore::HTMLNames::isNameOfInlineEventHandler):
+        (WebCore::XSSFilter::filterToken):
+        (WebCore::XSSFilter::filterTokenInitial):
+        (WebCore::XSSFilter::filterTokenAfterScriptStartTag):
+        (WebCore::XSSFilter::filterScriptToken):
+        (WebCore::XSSFilter::filterObjectToken):
+        (WebCore::XSSFilter::filterEmbedToken):
+        (WebCore::XSSFilter::filterAppletToken):
+        (WebCore::XSSFilter::filterMetaToken):
+        (WebCore::XSSFilter::filterBaseToken):
+        (WebCore::XSSFilter::eraseInlineEventHandlersIfInjected):
+        * html/parser/XSSFilter.h:
+
+2011-01-28  Adam Barth  <abarth at webkit.org>
+
         Reviewed by Daniel Bates.
 
         Wire up settings->xssAuditorEnabled to XSSFilter
diff --git a/Source/WebCore/html/parser/XSSFilter.cpp b/Source/WebCore/html/parser/XSSFilter.cpp
index eedef98..b2771a0 100644
--- a/Source/WebCore/html/parser/XSSFilter.cpp
+++ b/Source/WebCore/html/parser/XSSFilter.cpp
@@ -60,10 +60,10 @@ bool findAttributeWithName(const HTMLToken& token, const QualifiedName& name, si
     return false;
 }
 
-bool isNameOfScriptCarryingAttribute(const Vector<UChar, 32>& name)
+bool isNameOfInlineEventHandler(const Vector<UChar, 32>& name)
 {
-    const size_t lengthOfShortestScriptCarryingAttribute = 5; // To wit: oncut.
-    if (name.size() < lengthOfShortestScriptCarryingAttribute)
+    const size_t lengthOfShortestInlineEventHandlerName = 5; // To wit: oncut.
+    if (name.size() < lengthOfShortestInlineEventHandlerName)
         return false;
     return name[0] == 'o' && name[1] == 'n';
 }
@@ -104,56 +104,61 @@ void XSSFilter::filterToken(HTMLToken& token)
     if (!m_isEnabled)
         return;
 
+    bool didBlockScript = false;
+
     switch (m_state) {
     case Initial: 
+        didBlockScript = filterTokenInitial(token);
         break;
     case AfterScriptStartTag:
-        filterTokenAfterScriptStartTag(token);
+        didBlockScript = filterTokenAfterScriptStartTag(token);
         ASSERT(m_state == Initial);
         m_cachedSnippet = String();
-        return;
+        break;
     }
 
-    if (token.type() != HTMLToken::StartTag)
-        return;
-
-    if (hasName(token, scriptTag))
-        return filterScriptToken(token);
-
-    if (hasName(token, objectTag))
-        return filterObjectToken(token);
-
-    if (hasName(token, embedTag))
-        return filterEmbedToken(token);
+    if (didBlockScript) {
+        // FIXME: Consider using a more helpful console message.
+        DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n"));
+        // FIXME: We should add the real line number to the console.
+        m_parser->document()->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String());
+    }
+#endif
+}
 
-    if (hasName(token, appletTag))
-        return filterAppletToken(token);
+bool XSSFilter::filterTokenInitial(HTMLToken& token)
+{
+    ASSERT(m_state == Initial);
 
-    if (hasName(token, metaTag))
-        return filterMetaToken(token);
+    if (token.type() != HTMLToken::StartTag)
+        return false;
 
-    if (hasName(token, baseTag))
-        return filterBaseToken(token);
+    bool didBlockScript = eraseInlineEventHandlersIfInjected(token);
 
-    for (size_t i = 0; i < token.attributes().size(); ++i) {
-        const HTMLToken::Attribute& attribute = token.attributes().at(i);
-        if (!isNameOfScriptCarryingAttribute(attribute.m_name))
-            continue;
-        if (!isContainedInRequest(snippetForAttribute(token, attribute)))
-            continue;
-        token.eraseValueOfAttribute(i);
-    }
-#endif
+    if (hasName(token, scriptTag))
+        didBlockScript |= filterScriptToken(token);
+    else if (hasName(token, objectTag))
+        didBlockScript |= filterObjectToken(token);
+    else if (hasName(token, embedTag))
+        didBlockScript |= filterEmbedToken(token);
+    else if (hasName(token, appletTag))
+        didBlockScript |= filterAppletToken(token);
+    else if (hasName(token, metaTag))
+        didBlockScript |= filterMetaToken(token);
+    else if (hasName(token, baseTag))
+        didBlockScript |= filterBaseToken(token);
+
+    return didBlockScript;
 }
 
-void XSSFilter::filterTokenAfterScriptStartTag(HTMLToken& token)
+bool XSSFilter::filterTokenAfterScriptStartTag(HTMLToken& token)
 {
     ASSERT(m_state == AfterScriptStartTag);
     m_state = Initial;
 
     if (token.type() != HTMLToken::Character) {
         ASSERT(token.type() == HTMLToken::EndTag || token.type() == HTMLToken::EndOfFile);
-        return;
+        return false;
     }
 
     int start = 0;
@@ -163,69 +168,99 @@ void XSSFilter::filterTokenAfterScriptStartTag(HTMLToken& token)
     if (isContainedInRequest(m_cachedSnippet + snippetForRange(token, start, end))) {
         token.eraseCharacters();
         token.appendToCharacter(' '); // Technically, character tokens can't be empty.
+        return true;
     }
+    return false;
 }
 
-void XSSFilter::filterScriptToken(HTMLToken& token)
+bool XSSFilter::filterScriptToken(HTMLToken& token)
 {
     ASSERT(m_state == Initial);
     ASSERT(token.type() == HTMLToken::StartTag);
     ASSERT(hasName(token, scriptTag));
 
     if (eraseAttributeIfInjected(token, srcAttr))
-        return;
+        return true;
 
     m_state = AfterScriptStartTag;
     m_cachedSnippet = m_parser->sourceForToken(token);
+    return false;
 }
 
-void XSSFilter::filterObjectToken(HTMLToken& token)
+bool XSSFilter::filterObjectToken(HTMLToken& token)
 {
     ASSERT(m_state == Initial);
     ASSERT(token.type() == HTMLToken::StartTag);
     ASSERT(hasName(token, objectTag));
 
-    eraseAttributeIfInjected(token, dataAttr);
-    eraseAttributeIfInjected(token, typeAttr);
-    eraseAttributeIfInjected(token, classidAttr);
+    bool didBlockScript = false;
+
+    didBlockScript |= eraseAttributeIfInjected(token, dataAttr);
+    didBlockScript |= eraseAttributeIfInjected(token, typeAttr);
+    didBlockScript |= eraseAttributeIfInjected(token, classidAttr);
+
+    return didBlockScript;
 }
 
-void XSSFilter::filterEmbedToken(HTMLToken& token)
+bool XSSFilter::filterEmbedToken(HTMLToken& token)
 {
     ASSERT(m_state == Initial);
     ASSERT(token.type() == HTMLToken::StartTag);
     ASSERT(hasName(token, embedTag));
 
-    eraseAttributeIfInjected(token, srcAttr);
-    eraseAttributeIfInjected(token, typeAttr);
+    bool didBlockScript = false;
+
+    didBlockScript |= eraseAttributeIfInjected(token, srcAttr);
+    didBlockScript |= eraseAttributeIfInjected(token, typeAttr);
+
+    return didBlockScript;
 }
 
-void XSSFilter::filterAppletToken(HTMLToken& token)
+bool XSSFilter::filterAppletToken(HTMLToken& token)
 {
     ASSERT(m_state == Initial);
     ASSERT(token.type() == HTMLToken::StartTag);
     ASSERT(hasName(token, appletTag));
 
-    eraseAttributeIfInjected(token, codeAttr);
-    eraseAttributeIfInjected(token, objectAttr);
+    bool didBlockScript = false;
+
+    didBlockScript |= eraseAttributeIfInjected(token, codeAttr);
+    didBlockScript |= eraseAttributeIfInjected(token, objectAttr);
+
+    return didBlockScript;
 }
 
-void XSSFilter::filterMetaToken(HTMLToken& token)
+bool XSSFilter::filterMetaToken(HTMLToken& token)
 {
     ASSERT(m_state == Initial);
     ASSERT(token.type() == HTMLToken::StartTag);
     ASSERT(hasName(token, metaTag));
 
-    eraseAttributeIfInjected(token, http_equivAttr);
+    return eraseAttributeIfInjected(token, http_equivAttr);
 }
 
-void XSSFilter::filterBaseToken(HTMLToken& token)
+bool XSSFilter::filterBaseToken(HTMLToken& token)
 {
     ASSERT(m_state == Initial);
     ASSERT(token.type() == HTMLToken::StartTag);
     ASSERT(hasName(token, baseTag));
 
-    eraseAttributeIfInjected(token, hrefAttr);
+    return eraseAttributeIfInjected(token, hrefAttr);
+}
+
+bool XSSFilter::eraseInlineEventHandlersIfInjected(HTMLToken& token)
+{
+    bool didBlockScript = false;
+    for (size_t i = 0; i < token.attributes().size(); ++i) {
+        const HTMLToken::Attribute& attribute = token.attributes().at(i);
+        if (!isNameOfInlineEventHandler(attribute.m_name))
+            continue;
+        if (!isContainedInRequest(snippetForAttribute(token, attribute)))
+            continue;
+        token.eraseValueOfAttribute(i);
+        didBlockScript = true;
+    }
+    return didBlockScript;
 }
 
 bool XSSFilter::eraseAttributeIfInjected(HTMLToken& token, const QualifiedName& attributeName)
diff --git a/Source/WebCore/html/parser/XSSFilter.h b/Source/WebCore/html/parser/XSSFilter.h
index c7df0eb..23e04b3 100644
--- a/Source/WebCore/html/parser/XSSFilter.h
+++ b/Source/WebCore/html/parser/XSSFilter.h
@@ -45,14 +45,17 @@ private:
         AfterScriptStartTag,
     };
 
-    void filterTokenAfterScriptStartTag(HTMLToken&);
-    void filterScriptToken(HTMLToken&);
-    void filterObjectToken(HTMLToken&);
-    void filterEmbedToken(HTMLToken&);
-    void filterAppletToken(HTMLToken&);
-    void filterMetaToken(HTMLToken&);
-    void filterBaseToken(HTMLToken&);
+    bool filterTokenInitial(HTMLToken&);
+    bool filterTokenAfterScriptStartTag(HTMLToken&);
 
+    bool filterScriptToken(HTMLToken&);
+    bool filterObjectToken(HTMLToken&);
+    bool filterEmbedToken(HTMLToken&);
+    bool filterAppletToken(HTMLToken&);
+    bool filterMetaToken(HTMLToken&);
+    bool filterBaseToken(HTMLToken&);
+
+    bool eraseInlineEventHandlersIfInjected(HTMLToken&);
     bool eraseAttributeIfInjected(HTMLToken&, const QualifiedName&);
 
     String snippetForRange(const HTMLToken&, int start, int end);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list