[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9

enrica at apple.com enrica at apple.com
Thu Feb 4 21:24:02 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit d6e3eafa109024c14d31fea3f4f4db0f2ba12d5c
Author: enrica at apple.com <enrica at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Jan 22 00:40:23 2010 +0000

    Script tags are copied and pasted, making cross-domain attacks possible.
    https://bugs.webkit.org/show_bug.cgi?id=33970
    
    Reviewed by Darin Adler.
    
    WebCore:
    
    Tests: editing/pasteboard/paste-noscript-svg.html
           editing/pasteboard/paste-visible-script.html
    
    We remove the content and the attributes of every script tag before
    pasting into the destination.
    
    * dom/Element.cpp:
    (WebCore::Element::setAttributeMap): Now we are removing xlink:href
    if it contains javascript protocol.
    * html/HTMLParser.cpp:
    (WebCore::HTMLParser::parseToken): We strip all the script tag attributes
    we are parsing to create a fragment to paste.
    * html/HTMLTokenizer.cpp:
    (WebCore::HTMLTokenizer::HTMLTokenizer):
    (WebCore::HTMLTokenizer::scriptHandler): Removes the script text after it was parsed.
    * html/HTMLTokenizer.h:
    
    LayoutTests:
    
    * editing/pasteboard/paste-noscript-svg-expected.txt: Added.
    * editing/pasteboard/paste-noscript-svg.html: Added.
    * editing/pasteboard/paste-visible-script-expected.txt: Added.
    * editing/pasteboard/paste-visible-script.html: Added.
    * editing/resources/svgcontent.xhtml: Added.
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53659 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index f91a5ff..bebf6f5 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,16 @@
+2010-01-21  Enrica Casucci  <enrica at apple.com>
+
+        Reviewed by Darin Adler.
+
+        Script tags are copied and pasted, making cross-domain attacks possible.
+        https://bugs.webkit.org/show_bug.cgi?id=33970
+
+        * editing/pasteboard/paste-noscript-svg-expected.txt: Added.
+        * editing/pasteboard/paste-noscript-svg.html: Added.
+        * editing/pasteboard/paste-visible-script-expected.txt: Added.
+        * editing/pasteboard/paste-visible-script.html: Added.
+        * editing/resources/svgcontent.xhtml: Added.
+
 2010-01-21  Nikolas Zimmermann  <nzimmermann at rim.com>
 
         Reviewed by Dirk Schulze.
diff --git a/LayoutTests/editing/pasteboard/paste-noscript-svg-expected.txt b/LayoutTests/editing/pasteboard/paste-noscript-svg-expected.txt
new file mode 100644
index 0000000..6ab73c3
--- /dev/null
+++ b/LayoutTests/editing/pasteboard/paste-noscript-svg-expected.txt
@@ -0,0 +1,6 @@
+This test copies the content of an iframe and pastes it in an editable area and verifies that no script, handlers or javascript urls are copied.
+
+Hello 
+ 
+world
+<div id="div1">Hello&nbsp;</div><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="5cm" height="3cm" viewbox="0 0 5 3" version="1.1"><a xlink:href=""><ellipse cx="2.5" cy="1.5" rx="2" ry="1" fill="red"></ellipse></a></svg>&nbsp;<div id="div2">world</div>
diff --git a/LayoutTests/editing/pasteboard/paste-noscript-svg.html b/LayoutTests/editing/pasteboard/paste-noscript-svg.html
new file mode 100644
index 0000000..a76f9cd
--- /dev/null
+++ b/LayoutTests/editing/pasteboard/paste-noscript-svg.html
@@ -0,0 +1,39 @@
+<div id="description">
+This test copies the content of an iframe and pastes it
+in an editable area and verifies that no script, handlers or javascript urls are copied.
+</div>
+<iframe id="iframe1" src="../resources/svgcontent.xhtml" onload="foo()"></iframe>
+<div id="pastehere" contenteditable="true"></div>
+<ul id="console"></ul>
+<script>
+if (window.layoutTestController)
+     window.layoutTestController.dumpAsText();
+
+if (window.layoutTestController)
+    window.layoutTestController.waitUntilDone();
+
+function foo() {
+    var frame = frames[0];
+    var sel = frame.getSelection();
+    var doc = frame.document;
+    sel.setPosition(doc.body, 0);
+    doc.execCommand("SelectAll");
+    doc.execCommand("Copy");
+
+    var p1 = document.getElementById("pastehere");
+    var s = window.getSelection();
+    s.setPosition(p1, 0);
+    document.execCommand("Paste");
+    log(document.getElementById("pastehere").innerHTML);
+
+    if (window.layoutTestController)
+        window.layoutTestController.notifyDone();
+}
+
+function log(str) {
+    var li = document.createElement("li");
+    li.appendChild(document.createTextNode(str));
+    var console = document.getElementById("console");
+    console.appendChild(li);
+}
+</script>
diff --git a/LayoutTests/editing/pasteboard/paste-visible-script-expected.txt b/LayoutTests/editing/pasteboard/paste-visible-script-expected.txt
new file mode 100644
index 0000000..905a885
--- /dev/null
+++ b/LayoutTests/editing/pasteboard/paste-visible-script-expected.txt
@@ -0,0 +1,6 @@
+Hello
+function sayHello() { alert("Hello"); }
+World
+Hello
+World
+<div id="pastehere" contenteditable="true">Hello<script></script><script></script><div id="test2">World</div></div>
diff --git a/LayoutTests/editing/pasteboard/paste-visible-script.html b/LayoutTests/editing/pasteboard/paste-visible-script.html
new file mode 100644
index 0000000..d6dd1a7
--- /dev/null
+++ b/LayoutTests/editing/pasteboard/paste-visible-script.html
@@ -0,0 +1,46 @@
+<body>
+<div id="test1" >
+Hello
+<script style="display: block">
+function sayHello()
+{
+    alert("Hello");
+}
+</script>
+<script>
+function foo() {
+    var i = 10;
+    if (i >= 10)
+        alert('foo');
+}
+</script>
+<script style="display: block" src="../editing.js">
+</script>
+<div id="test2">
+World
+</div>
+<div id="pastehere" contenteditable="true"></div>
+<ul id="console"></ul>
+<script>
+if (window.layoutTestController)
+     layoutTestController.dumpAsText();
+
+var s = window.getSelection();
+var p1 = document.getElementById("test1");
+s.setPosition(p1, 0);
+s.setBaseAndExtent(p1, 0, document.getElementById("test2"), 2);
+document.execCommand("Copy");
+p1 = document.getElementById("pastehere");
+s.setPosition(p1, 0);
+document.execCommand("Paste");
+
+log(document.getElementById("pastehere").outerHTML);
+
+function log(str) {
+    var li = document.createElement("li");
+    li.appendChild(document.createTextNode(str));
+    var console = document.getElementById("console");
+    console.appendChild(li);
+}
+</script>
+</body>
diff --git a/LayoutTests/editing/resources/svgcontent.xhtml b/LayoutTests/editing/resources/svgcontent.xhtml
new file mode 100644
index 0000000..22ee410
--- /dev/null
+++ b/LayoutTests/editing/resources/svgcontent.xhtml
@@ -0,0 +1,14 @@
+<?xml version="1.0" standalone="no"?>
+<body>
+<div id="div1">
+Hello
+</div>
+<svg width="5cm" height="3cm" viewBox="0 0 5 3" version="1.1"
+     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <a xlink:href="javascript:alert('hello Enrica')">
+    <ellipse cx="2.5" cy="1.5" rx="2" ry="1"
+             fill="red" />
+  </a>
+</svg>
+<div id="div2">world</div>
+</body>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 2e26092..3a32a6a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,27 @@
+2010-01-21  Enrica Casucci  <enrica at apple.com>
+
+        Reviewed by Darin Adler.
+
+        Script tags are copied and pasted, making cross-domain attacks possible.
+        https://bugs.webkit.org/show_bug.cgi?id=33970
+
+        Tests: editing/pasteboard/paste-noscript-svg.html
+               editing/pasteboard/paste-visible-script.html
+
+        We remove the content and the attributes of every script tag before
+        pasting into the destination.
+        
+        * dom/Element.cpp:
+        (WebCore::Element::setAttributeMap): Now we are removing xlink:href
+        if it contains javascript protocol.
+        * html/HTMLParser.cpp:
+        (WebCore::HTMLParser::parseToken): We strip all the script tag attributes
+        we are parsing to create a fragment to paste.
+        * html/HTMLTokenizer.cpp:
+        (WebCore::HTMLTokenizer::HTMLTokenizer):
+        (WebCore::HTMLTokenizer::scriptHandler): Removes the script text after it was parsed.
+        * html/HTMLTokenizer.h:
+
 2010-01-21  Nikolas Zimmermann  <nzimmermann at rim.com>
 
         Reviewed by Dirk Schulze.
diff --git a/WebCore/dom/Element.cpp b/WebCore/dom/Element.cpp
index 234bec4..544532d 100644
--- a/WebCore/dom/Element.cpp
+++ b/WebCore/dom/Element.cpp
@@ -643,7 +643,8 @@ void Element::setAttributeMap(PassRefPtr<NamedNodeMap> list, FragmentScriptingPe
                     namedAttrMap->m_attributes.remove(i);
                     continue;
                 }
-                if ((attributeName == hrefAttr || attributeName == srcAttr || attributeName == actionAttr) && protocolIsJavaScript(deprecatedParseURL(namedAttrMap->m_attributes[i]->value())))
+
+                if ((attributeName.localName().endsWith(hrefAttr.localName()) || attributeName == srcAttr || attributeName == actionAttr) && protocolIsJavaScript(deprecatedParseURL(namedAttrMap->m_attributes[i]->value())))
                     namedAttrMap->m_attributes[i]->setValue(nullAtom);
                 i++;
             }
diff --git a/WebCore/html/HTMLParser.cpp b/WebCore/html/HTMLParser.cpp
index f4ae6c2..f116bff 100644
--- a/WebCore/html/HTMLParser.cpp
+++ b/WebCore/html/HTMLParser.cpp
@@ -277,7 +277,8 @@ PassRefPtr<Node> HTMLParser::parseToken(Token* t)
     // set attributes
     if (n->isHTMLElement()) {
         HTMLElement* e = static_cast<HTMLElement*>(n.get());
-        e->setAttributeMap(t->attrs.get(), m_scriptingPermission);
+        if (m_scriptingPermission == FragmentScriptingAllowed || t->tagName != scriptTag)
+            e->setAttributeMap(t->attrs.get(), m_scriptingPermission);
 
         // take care of optional close tags
         if (e->endTagRequirement() == TagStatusOptional)
diff --git a/WebCore/html/HTMLTokenizer.cpp b/WebCore/html/HTMLTokenizer.cpp
index a8388e8..94a1c1e 100644
--- a/WebCore/html/HTMLTokenizer.cpp
+++ b/WebCore/html/HTMLTokenizer.cpp
@@ -172,6 +172,7 @@ HTMLTokenizer::HTMLTokenizer(HTMLDocument* doc, bool reportErrors)
     , m_parser(new HTMLParser(doc, reportErrors))
     , m_inWrite(false)
     , m_fragment(false)
+    , m_scriptingPermission(FragmentScriptingAllowed)
 {
     begin();
 }
@@ -192,6 +193,7 @@ HTMLTokenizer::HTMLTokenizer(HTMLViewSourceDocument* doc)
     , m_parser(0)
     , m_inWrite(false)
     , m_fragment(false)
+    , m_scriptingPermission(FragmentScriptingAllowed)
 {
     begin();
 }
@@ -211,6 +213,7 @@ HTMLTokenizer::HTMLTokenizer(DocumentFragment* frag, FragmentScriptingPermission
     , m_parser(new HTMLParser(frag, scriptingPermission))
     , m_inWrite(false)
     , m_fragment(true)
+    , m_scriptingPermission(scriptingPermission)
 {
     begin();
 }
@@ -468,6 +471,13 @@ HTMLTokenizer::State HTMLTokenizer::scriptHandler(State state)
 
     state = processListing(SegmentedString(m_scriptCode, m_scriptCodeSize), state);
     RefPtr<Node> node = processToken();
+    
+    if (node && m_scriptingPermission == FragmentScriptingNotAllowed) {
+        ExceptionCode ec;
+        node->remove(ec);
+        node = 0;
+    }
+    
     String scriptString = node ? node->textContent() : "";
     m_currentToken.tagName = scriptTag.localName();
     m_currentToken.beginTag = false;
diff --git a/WebCore/html/HTMLTokenizer.h b/WebCore/html/HTMLTokenizer.h
index 863095a..ef7cbfc 100644
--- a/WebCore/html/HTMLTokenizer.h
+++ b/WebCore/html/HTMLTokenizer.h
@@ -421,6 +421,7 @@ private:
     OwnPtr<HTMLParser> m_parser;
     bool m_inWrite;
     bool m_fragment;
+    FragmentScriptingPermission m_scriptingPermission;
 
     OwnPtr<PreloadScanner> m_preloadScanner;
 };

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list