2009-12-01 Patrik Persson <patrik.j.persson@ericsson.com>
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Dec 2009 02:40:35 +0000 (02:40 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 2 Dec 2009 02:40:35 +0000 (02:40 +0000)
        Reviewed by Darin Adler.

        Implement HTML5 sandbox attribute for iframes.
        http://www.w3.org/TR/html5/text-level-semantics.html#attr-iframe-sandbox
        https://bugs.webkit.org/show_bug.cgi?id=21288

        * fast/frames/resources/non-sandboxed-iframe-navigation.html: Added.
        * fast/frames/resources/sandboxed-iframe-attribute-parsing-allowed.html: Added.
        * fast/frames/resources/sandboxed-iframe-attribute-parsing-disallowed.html: Added.
        * fast/frames/resources/sandboxed-iframe-form-allowed.html: Added.
        * fast/frames/resources/sandboxed-iframe-form-disallowed.html: Added.
        * fast/frames/resources/sandboxed-iframe-navigated.html: Added.
        * fast/frames/resources/sandboxed-iframe-navigation-child.html: Added.
        * fast/frames/resources/sandboxed-iframe-navigation-navigated.html: Added.
        * fast/frames/resources/sandboxed-iframe-navigation-parent.html: Added.
        * fast/frames/resources/sandboxed-iframe-navigation-source.html: Added.
        * fast/frames/resources/sandboxed-iframe-navigation-targetlink.html: Added.
        * fast/frames/resources/sandboxed-iframe-navigation-windowopen.html: Added.
        * fast/frames/resources/sandboxed-iframe-plugins-frame-applet.html: Added.
        * fast/frames/resources/sandboxed-iframe-plugins-frame-embed.html: Added.
        * fast/frames/resources/sandboxed-iframe-plugins-frame-object.html: Added.
        * fast/frames/resources/sandboxed-iframe-script-dynamic.html: Added.
        * fast/frames/resources/sandboxed-iframe-storage-allowed.html: Added.
        * fast/frames/resources/sandboxed-iframe-storage-disallowed.html: Added.
        * fast/frames/sandboxed-iframe-attribute-parsing-expected.txt: Added.
        * fast/frames/sandboxed-iframe-attribute-parsing.html: Added.
        * fast/frames/sandboxed-iframe-forms-expected.txt: Added.
        * fast/frames/sandboxed-iframe-forms.html: Added.
        * fast/frames/sandboxed-iframe-navigation-allowed-expected.txt: Added.
        * fast/frames/sandboxed-iframe-navigation-allowed.html: Added.
        * fast/frames/sandboxed-iframe-navigation-parent-expected.txt: Added.
        * fast/frames/sandboxed-iframe-navigation-parent.html: Added.
        * fast/frames/sandboxed-iframe-navigation-targetlink-expected.txt: Added.
        * fast/frames/sandboxed-iframe-navigation-targetlink.html: Added.
        * fast/frames/sandboxed-iframe-navigation-windowopen-expected.txt: Added.
        * fast/frames/sandboxed-iframe-navigation-windowopen.html: Added.
        * fast/frames/sandboxed-iframe-plugins-expected.txt: Added.
        * fast/frames/sandboxed-iframe-plugins.html: Added.
        * fast/frames/sandboxed-iframe-scripting-expected.txt: Added.
        * fast/frames/sandboxed-iframe-scripting.html: Added.
        * fast/frames/sandboxed-iframe-storage-expected.txt: Added.
        * fast/frames/sandboxed-iframe-storage.html: Added.
        * http/tests/security/resources/sandboxed-iframe-document-cookie-read-denied.html: Added.
        * http/tests/security/resources/sandboxed-iframe-modify-self.html: Added.
        * http/tests/security/resources/xss-DENIED-sandboxed-iframe-attacker.html: Added.
        * http/tests/security/sandboxed-iframe-document-cookie-expected.txt: Added.
        * http/tests/security/sandboxed-iframe-document-cookie.html: Added.
        * http/tests/security/sandboxed-iframe-modify-self-expected.txt: Added.
        * http/tests/security/sandboxed-iframe-modify-self.html: Added.
        * http/tests/security/xss-DENIED-sandboxed-iframe-expected.txt: Added.
        * http/tests/security/xss-DENIED-sandboxed-iframe.html: Added.
        * http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow-expected.txt: Added.
        * http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow.html: Added.
        * http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-expected.txt: Added.
        * http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard-expected.txt: Added.
        * http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard.html: Added.
        * http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied.html: Added.
        * http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow-iframe.html: Added.
        * http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow.cgi: Added.
        * http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-iframe.html: Added.
        * http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard-iframe.html: Added.
        * http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard.cgi: Added.
        * http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied.cgi: Added.
2009-12-01  Patrik Persson  <patrik.j.persson@ericsson.com>

        Reviewed by Darin Adler.

        Implement HTML5 sandbox attribute for iframes.
        http://www.w3.org/TR/html5/text-level-semantics.html#attr-iframe-sandbox
        https://bugs.webkit.org/show_bug.cgi?id=21288

        Tests: fast/frames/sandboxed-iframe-attribute-parsing.html
               fast/frames/sandboxed-iframe-forms.html
               fast/frames/sandboxed-iframe-navigation-allowed.html
               fast/frames/sandboxed-iframe-navigation-parent.html
               fast/frames/sandboxed-iframe-navigation-targetlink.html
               fast/frames/sandboxed-iframe-navigation-windowopen.html
               fast/frames/sandboxed-iframe-plugins.html
               fast/frames/sandboxed-iframe-scripting.html
               fast/frames/sandboxed-iframe-storage.html
               http/tests/security/sandboxed-iframe-document-cookie.html
               http/tests/security/sandboxed-iframe-modify-self.html
               http/tests/security/xss-DENIED-sandboxed-iframe.html
               http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow.html
               http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard.html
               http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied.html

        * bindings/js/JSDOMWindowCustom.cpp: sandboxing navigation
        (WebCore::createWindow):
        * bindings/js/ScriptController.cpp: sandboxing scripts
        (WebCore::ScriptController::isEnabled):
        * dom/Document.cpp:
        (WebCore::Document::processHttpEquiv):
        (WebCore::Document::cookie): raise exception when accessed from sandbox
        (WebCore::Document::setCookie): raise exception when accessed from sandbox
        (WebCore::Document::initSecurityContext): updae sandbox status
        (WebCore::Document::updateSandboxFlags):
        * dom/Document.h:
        * dom/Document.idl:
        * html/HTMLAppletElement.cpp: sandboxing applets
        (WebCore::HTMLAppletElement::createRenderer):
        (WebCore::HTMLAppletElement::renderWidgetForJSBindings):
        (WebCore::HTMLAppletElement::canEmbedJava):
        * html/HTMLAppletElement.h:
        * html/HTMLAttributeNames.in:
        * html/HTMLFrameOwnerElement.cpp: management of sandbox flags as stated in attribute
        (WebCore::HTMLFrameOwnerElement::HTMLFrameOwnerElement):
        (WebCore::HTMLFrameOwnerElement::setSandboxFlags):
        * html/HTMLFrameOwnerElement.h:
        (WebCore::HTMLFrameOwnerElement::sandboxFlags):
        * html/HTMLIFrameElement.cpp: sandbox attribute parsing
        (WebCore::parseSandboxAttribute):
        (WebCore::HTMLIFrameElement::parseMappedAttribute):
        * html/HTMLIFrameElement.idl:
        * inspector/InspectorController.cpp:
        (WebCore::InspectorController::getCookies):
        * loader/CrossOriginAccessControl.cpp:
        (WebCore::passesAccessControlCheck):
        * loader/FrameLoader.cpp:
        (WebCore::FrameLoader::FrameLoader):
        (WebCore::FrameLoader::init):
        (WebCore::FrameLoader::submitForm): sandboxing forms
        (WebCore::FrameLoader::requestObject): sandboxing plugins
        (WebCore::FrameLoader::shouldAllowNavigation): sandboxing navigation
        (WebCore::FrameLoader::updateSandboxFlags): propagation of sandbox flags
        * loader/FrameLoader.h:
        (WebCore::FrameLoader::ownerElementSandboxFlagsChanged):
        (WebCore::FrameLoader::isSandboxed):
        (WebCore::FrameLoader::sandboxFlags):
        * loader/FrameLoaderTypes.h:
        (WebCore::):
        * page/DOMWindow.cpp: disable storage and databases in sandboxed frames
        (WebCore::DOMWindow::sessionStorage):
        (WebCore::DOMWindow::localStorage):
        (WebCore::DOMWindow::openDatabase):
        * page/SecurityOrigin.cpp: added sandboxing status
        (WebCore::SecurityOrigin::SecurityOrigin):
        (WebCore::SecurityOrigin::canAccess):
        (WebCore::SecurityOrigin::canRequest):
        (WebCore::SecurityOrigin::toString):
        * page/SecurityOrigin.h:
        (WebCore::SecurityOrigin::setSandboxFlags):
        (WebCore::SecurityOrigin::isSandboxed):
        (WebCore::SecurityOrigin::canAccessDatabase):
        (WebCore::SecurityOrigin::canAccessStorage):
        * websockets/WebSocketChannel.cpp:
        (WebCore::WebSocketChannel::didReceiveData):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@51577 268f45cc-cd09-0410-ab3c-d52691b4dbfc

78 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/frames/resources/non-sandboxed-iframe-navigation.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-attribute-parsing-allowed.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-attribute-parsing-disallowed.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-form-allowed.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-form-disallowed.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-navigated.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-child.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-navigated.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-parent.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-source.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-targetlink.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-windowopen.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-plugins-frame-applet.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-plugins-frame-embed.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-plugins-frame-object.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-script-dynamic.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-storage-allowed.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/sandboxed-iframe-storage-disallowed.html [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-forms-expected.txt [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-forms.html [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-navigation-allowed-expected.txt [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-navigation-allowed.html [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-navigation-parent-expected.txt [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-navigation-parent.html [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-navigation-targetlink-expected.txt [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-navigation-targetlink.html [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-navigation-windowopen-expected.txt [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-navigation-windowopen.html [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-plugins-expected.txt [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-plugins.html [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-scripting-expected.txt [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-scripting.html [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-storage-expected.txt [new file with mode: 0644]
LayoutTests/fast/frames/sandboxed-iframe-storage.html [new file with mode: 0644]
LayoutTests/http/tests/security/resources/sandboxed-iframe-document-cookie-read-denied.html [new file with mode: 0644]
LayoutTests/http/tests/security/resources/sandboxed-iframe-modify-self.html [new file with mode: 0644]
LayoutTests/http/tests/security/resources/xss-DENIED-sandboxed-iframe-attacker.html [new file with mode: 0644]
LayoutTests/http/tests/security/sandboxed-iframe-document-cookie-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/sandboxed-iframe-document-cookie.html [new file with mode: 0644]
LayoutTests/http/tests/security/sandboxed-iframe-modify-self-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/sandboxed-iframe-modify-self.html [new file with mode: 0644]
LayoutTests/http/tests/security/xss-DENIED-sandboxed-iframe-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/xss-DENIED-sandboxed-iframe.html [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow.html [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard.html [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied.html [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow-iframe.html [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow.cgi [new file with mode: 0755]
LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-iframe.html [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard-iframe.html [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard.cgi [new file with mode: 0755]
LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied.cgi [new file with mode: 0755]
WebCore/ChangeLog
WebCore/bindings/js/JSDOMWindowCustom.cpp
WebCore/bindings/js/ScriptController.cpp
WebCore/dom/Document.cpp
WebCore/dom/Document.h
WebCore/dom/Document.idl
WebCore/html/HTMLAppletElement.cpp
WebCore/html/HTMLAppletElement.h
WebCore/html/HTMLAttributeNames.in
WebCore/html/HTMLFrameOwnerElement.cpp
WebCore/html/HTMLFrameOwnerElement.h
WebCore/html/HTMLIFrameElement.cpp
WebCore/html/HTMLIFrameElement.idl
WebCore/inspector/InspectorController.cpp
WebCore/loader/CrossOriginAccessControl.cpp
WebCore/loader/FrameLoader.cpp
WebCore/loader/FrameLoader.h
WebCore/loader/FrameLoaderTypes.h
WebCore/page/DOMWindow.cpp
WebCore/page/SecurityOrigin.cpp
WebCore/page/SecurityOrigin.h
WebCore/websockets/WebSocketChannel.cpp

index 4257e91..ad11570 100644 (file)
@@ -1,3 +1,69 @@
+2009-12-01  Patrik Persson  <patrik.j.persson@ericsson.com>
+
+        Reviewed by Darin Adler.
+
+        Implement HTML5 sandbox attribute for iframes.
+        http://www.w3.org/TR/html5/text-level-semantics.html#attr-iframe-sandbox
+        https://bugs.webkit.org/show_bug.cgi?id=21288
+
+        * fast/frames/resources/non-sandboxed-iframe-navigation.html: Added.
+        * fast/frames/resources/sandboxed-iframe-attribute-parsing-allowed.html: Added.
+        * fast/frames/resources/sandboxed-iframe-attribute-parsing-disallowed.html: Added.
+        * fast/frames/resources/sandboxed-iframe-form-allowed.html: Added.
+        * fast/frames/resources/sandboxed-iframe-form-disallowed.html: Added.
+        * fast/frames/resources/sandboxed-iframe-navigated.html: Added.
+        * fast/frames/resources/sandboxed-iframe-navigation-child.html: Added.
+        * fast/frames/resources/sandboxed-iframe-navigation-navigated.html: Added.
+        * fast/frames/resources/sandboxed-iframe-navigation-parent.html: Added.
+        * fast/frames/resources/sandboxed-iframe-navigation-source.html: Added.
+        * fast/frames/resources/sandboxed-iframe-navigation-targetlink.html: Added.
+        * fast/frames/resources/sandboxed-iframe-navigation-windowopen.html: Added.
+        * fast/frames/resources/sandboxed-iframe-plugins-frame-applet.html: Added.
+        * fast/frames/resources/sandboxed-iframe-plugins-frame-embed.html: Added.
+        * fast/frames/resources/sandboxed-iframe-plugins-frame-object.html: Added.
+        * fast/frames/resources/sandboxed-iframe-script-dynamic.html: Added.
+        * fast/frames/resources/sandboxed-iframe-storage-allowed.html: Added.
+        * fast/frames/resources/sandboxed-iframe-storage-disallowed.html: Added.
+        * fast/frames/sandboxed-iframe-attribute-parsing-expected.txt: Added.
+        * fast/frames/sandboxed-iframe-attribute-parsing.html: Added.
+        * fast/frames/sandboxed-iframe-forms-expected.txt: Added.
+        * fast/frames/sandboxed-iframe-forms.html: Added.
+        * fast/frames/sandboxed-iframe-navigation-allowed-expected.txt: Added.
+        * fast/frames/sandboxed-iframe-navigation-allowed.html: Added.
+        * fast/frames/sandboxed-iframe-navigation-parent-expected.txt: Added.
+        * fast/frames/sandboxed-iframe-navigation-parent.html: Added.
+        * fast/frames/sandboxed-iframe-navigation-targetlink-expected.txt: Added.
+        * fast/frames/sandboxed-iframe-navigation-targetlink.html: Added.
+        * fast/frames/sandboxed-iframe-navigation-windowopen-expected.txt: Added.
+        * fast/frames/sandboxed-iframe-navigation-windowopen.html: Added.
+        * fast/frames/sandboxed-iframe-plugins-expected.txt: Added.
+        * fast/frames/sandboxed-iframe-plugins.html: Added.
+        * fast/frames/sandboxed-iframe-scripting-expected.txt: Added.
+        * fast/frames/sandboxed-iframe-scripting.html: Added.
+        * fast/frames/sandboxed-iframe-storage-expected.txt: Added.
+        * fast/frames/sandboxed-iframe-storage.html: Added.
+        * http/tests/security/resources/sandboxed-iframe-document-cookie-read-denied.html: Added.
+        * http/tests/security/resources/sandboxed-iframe-modify-self.html: Added.
+        * http/tests/security/resources/xss-DENIED-sandboxed-iframe-attacker.html: Added.
+        * http/tests/security/sandboxed-iframe-document-cookie-expected.txt: Added.
+        * http/tests/security/sandboxed-iframe-document-cookie.html: Added.
+        * http/tests/security/sandboxed-iframe-modify-self-expected.txt: Added.
+        * http/tests/security/sandboxed-iframe-modify-self.html: Added.
+        * http/tests/security/xss-DENIED-sandboxed-iframe-expected.txt: Added.
+        * http/tests/security/xss-DENIED-sandboxed-iframe.html: Added.
+        * http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow-expected.txt: Added.
+        * http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow.html: Added.
+        * http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-expected.txt: Added.
+        * http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard-expected.txt: Added.
+        * http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard.html: Added.
+        * http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied.html: Added.
+        * http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow-iframe.html: Added.
+        * http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow.cgi: Added.
+        * http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-iframe.html: Added.
+        * http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard-iframe.html: Added.
+        * http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard.cgi: Added.
+        * http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied.cgi: Added.
+
 2009-12-01  Chris Fleizach  <cfleizach@apple.com>
 
         Reviewed by David Kilzer.
diff --git a/LayoutTests/fast/frames/resources/non-sandboxed-iframe-navigation.html b/LayoutTests/fast/frames/resources/non-sandboxed-iframe-navigation.html
new file mode 100644 (file)
index 0000000..2e49faf
--- /dev/null
@@ -0,0 +1,5 @@
+<html>
+<body>
+  <iframe src="sandboxed-iframe-navigation-source.html"></iframe>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-attribute-parsing-allowed.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-attribute-parsing-allowed.html
new file mode 100644 (file)
index 0000000..67ff97c
--- /dev/null
@@ -0,0 +1,12 @@
+<html>
+<script>
+
+top.allowedCallFromSandbox();
+
+</script>
+<body onload="document.getElementById('f').submit();">
+    <form id='f' action="javascript:top.disallowedFormSubmitted();">
+        <input name="x" value="y" type="checkbox" checked="yes" />
+    </form>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-attribute-parsing-disallowed.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-attribute-parsing-disallowed.html
new file mode 100644 (file)
index 0000000..b247936
--- /dev/null
@@ -0,0 +1,5 @@
+<html>
+<script>
+top.disallowedCallFromSandbox();
+</script>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-form-allowed.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-form-allowed.html
new file mode 100644 (file)
index 0000000..03519fe
--- /dev/null
@@ -0,0 +1,5 @@
+<body onload="document.getElementById('form').submit();">
+<form id="form" action="javascript:window.top.allowedFormSubmitted();">
+    <input name=x value=y type="checkbox" checked="yes"/>
+</form>
+</body>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-form-disallowed.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-form-disallowed.html
new file mode 100644 (file)
index 0000000..e19afb3
--- /dev/null
@@ -0,0 +1,6 @@
+<body onload="document.getElementById('form').submit();"
+      bgcolor='yellow'>
+<form id="form" action="javascript:window.top.disallowedFormSubmitted();">
+    <input name=x value=y type="checkbox" checked="yes"/>
+</form>
+</body>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-navigated.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-navigated.html
new file mode 100644 (file)
index 0000000..c1380cb
--- /dev/null
@@ -0,0 +1,5 @@
+<html>
+<body onload='self.top.countFrame();'>
+navigated
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-child.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-child.html
new file mode 100644 (file)
index 0000000..69b7651
--- /dev/null
@@ -0,0 +1,18 @@
+<html>
+<head>
+<script>
+function modify()
+{
+    self.navigated.location.assign("javascript: top.childFrameWasNavigated();");
+}
+</script>
+</head>
+<body onload="modify();">
+    <iframe name="navigated"
+            src="sandboxed-iframe-navigation-navigated.html">
+    </iframe>
+    <iframe name="frameWithPlugin"
+            src="sandboxed-iframe-plugins-frame-object.html">
+    </iframe>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-navigated.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-navigated.html
new file mode 100644 (file)
index 0000000..3d8e788
--- /dev/null
@@ -0,0 +1,9 @@
+<html>
+<head>
+</head>
+<body>
+<!-- This file is in a separate document in order to share origin with the
+parent document. -->
+innocent content
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-parent.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-parent.html
new file mode 100644 (file)
index 0000000..6b341a1
--- /dev/null
@@ -0,0 +1,8 @@
+<html>
+<body>
+    <iframe sandbox="allow-scripts allow-same-origin"
+            src="sandboxed-iframe-navigation-source.html">
+    </iframe>
+    <p id='innocent_content'>innocent content</p>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-source.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-source.html
new file mode 100644 (file)
index 0000000..413320a
--- /dev/null
@@ -0,0 +1,12 @@
+<html>
+<head>
+<script>
+function modify()
+{
+    self.parent.location.assign('sandboxed-iframe-navigated.html');
+}
+</script>
+</head>
+<body onload='modify();'>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-targetlink.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-targetlink.html
new file mode 100644 (file)
index 0000000..de156c5
--- /dev/null
@@ -0,0 +1,31 @@
+<html>
+<head>
+<script>
+
+/*
+ * Set the target of the link to 'X_target', where X is the name of
+ * this frame.
+ *
+ * Then click the link.
+ */
+
+function click_link()
+{
+    var event = document.createEvent('MouseEvent');
+    event.initEvent('click', true, true);
+    var link = document.getElementById('link');
+    link.target = self.name + '_target';
+    link.dispatchEvent(event);
+}
+
+</script>
+</head>
+
+<body onload='click_link();'>
+
+    <a href="sandboxed-iframe-navigated.html" id="link">
+        (link triggered by script)
+    </a>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-windowopen.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-navigation-windowopen.html
new file mode 100644 (file)
index 0000000..b0560a0
--- /dev/null
@@ -0,0 +1,3 @@
+<script>
+    window.open("javascript: opener.parent.windowOpened(opener);");
+</script>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-plugins-frame-applet.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-plugins-frame-applet.html
new file mode 100644 (file)
index 0000000..86bb9f9
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+</head>
+
+<body>
+    <applet name="app"
+            codebase="../../dom/resources"
+            code="TestApplet"
+    </applet>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-plugins-frame-embed.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-plugins-frame-embed.html
new file mode 100644 (file)
index 0000000..500ed7c
--- /dev/null
@@ -0,0 +1,12 @@
+<html>
+<head>
+</head>
+
+<body>
+    <embed id="plugin" 
+           type="application/x-webkit-test-netscape"
+           src="data:text/plain,"
+           style="width:0; height:0">
+    </embed>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-plugins-frame-object.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-plugins-frame-object.html
new file mode 100644 (file)
index 0000000..d7248cf
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+<head>
+</head>
+
+<body>
+    <object id="plugin" 
+            type="application/x-webkit-test-netscape"
+            style="width:0; height:0">
+    </object>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-script-dynamic.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-script-dynamic.html
new file mode 100644 (file)
index 0000000..998f6fb
--- /dev/null
@@ -0,0 +1,26 @@
+<html>
+<head>
+<script>
+
+    frame = window.top.document.getElementById('frame');
+
+    // setting the sandbox flag at runtime should not terminate already
+    // running scripts (e.g., this one)
+
+    frame.sandbox = 'allow-same-origin';   // NO allow-scripts
+
+    ++window.top.allowedExecuted;
+
+    // however, new scripts (such as the onload one below) should
+    // not run
+
+    function onload_hook()
+    {
+        ++window.top.disallowedExecuted;
+    };
+
+</script>
+</head>
+
+<body onload='onload_hook();'></body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-storage-allowed.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-storage-allowed.html
new file mode 100644 (file)
index 0000000..51705fa
--- /dev/null
@@ -0,0 +1,19 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="../../js/resources/js-test-post-function.js"></script>
+<script>
+
+window.onload = function() {
+    shouldBeTrue("window.openDatabase() != null");
+    shouldBeTrue("window.localStorage != null");
+    shouldBeTrue("window.sessionStorage != null");
+}
+
+</script>
+</head>
+<body>
+    <div id="console"></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/resources/sandboxed-iframe-storage-disallowed.html b/LayoutTests/fast/frames/resources/sandboxed-iframe-storage-disallowed.html
new file mode 100644 (file)
index 0000000..ee46bab
--- /dev/null
@@ -0,0 +1,19 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css">
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="../../js/resources/js-test-post-function.js"></script>
+<script>
+
+window.onload = function() {
+    shouldBeTrue("window.openDatabase() == null");
+    shouldBeTrue("window.localStorage == null");
+    shouldBeTrue("window.sessionStorage == null");
+}
+
+</script>
+</head>
+<body>
+    <div id="console"></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-forms-expected.txt b/LayoutTests/fast/frames/sandboxed-iframe-forms-expected.txt
new file mode 100644 (file)
index 0000000..5923f54
--- /dev/null
@@ -0,0 +1,4 @@
+This test runs five IFrames with forms allowed, one IFrame with forms disallowed, then five more IFrames with forms allowed. If ten form submissions are made, and the disallowed submission is not one of them, we consider the test to have passed. This test will print "PASS" on success.
+
+                    
+PASS
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-forms.html b/LayoutTests/fast/frames/sandboxed-iframe-forms.html
new file mode 100644 (file)
index 0000000..c2f8e61
--- /dev/null
@@ -0,0 +1,96 @@
+<html>
+<head>
+<script>
+
+if (window.layoutTestController) {
+    window.layoutTestController.dumpAsText();
+    window.layoutTestController.waitUntilDone();
+}
+
+var submissionCount      = 0;
+var disallowedSubmission = false;
+
+function allowedFormSubmitted()
+{
+    ++submissionCount;
+
+    if (submissionCount == 10) {
+        document.getElementById("test_status").innerHTML = (disallowedSubmission ? "FAIL" : "PASS");
+      
+        if (window.layoutTestController)
+            window.layoutTestController.notifyDone();
+    }
+}
+
+function disallowedFormSubmitted()
+{
+    disallowedSubmission = true;
+}
+
+</script>
+</head>
+
+<body>
+
+    <p>This test runs five IFrames with forms allowed, one IFrame with forms
+    disallowed, then five more IFrames with forms allowed. If ten form
+    submissions are made, and the disallowed submission is not one of them,
+    we consider the test to have passed. This test will print
+    &quot;PASS&quot; on success.</p>
+
+    <!-- five IFrames with forms allowed -->
+
+    <iframe style="width: 60px; height: 60px;"
+        sandbox="allow-scripts allow-forms"
+        src="resources/sandboxed-iframe-form-allowed.html">
+    </iframe>
+    <iframe style="width: 60px; height: 60px;"
+        sandbox="allow-scripts allow-forms"
+        src="resources/sandboxed-iframe-form-allowed.html">
+    </iframe>
+    <iframe style="width: 60px; height: 60px;"
+        sandbox="allow-scripts allow-forms"
+        src="resources/sandboxed-iframe-form-allowed.html">
+    </iframe>
+    <iframe style="width: 60px; height: 60px;"
+        sandbox="allow-scripts allow-forms"
+        src="resources/sandboxed-iframe-form-allowed.html">
+    </iframe>
+    <iframe style="width: 60px; height: 60px;"
+        sandbox="allow-scripts allow-forms"
+        src="resources/sandboxed-iframe-form-allowed.html">
+    </iframe>
+
+    <!-- one IFrame with forms disallowed -->
+
+    <iframe style="width: 60px; height: 60px;"
+        sandbox="allow-scripts"
+        src="resources/sandboxed-iframe-form-disallowed.html">
+    </iframe>
+
+    <!-- five more IFrames with forms allowed -->
+
+    <iframe style="width: 60px; height: 60px;"
+        sandbox="allow-scripts allow-forms"
+        src="resources/sandboxed-iframe-form-allowed.html">
+    </iframe>
+    <iframe style="width: 60px; height: 60px;"
+        sandbox="allow-scripts allow-forms"
+        src="resources/sandboxed-iframe-form-allowed.html">
+    </iframe>
+    <iframe style="width: 60px; height: 60px;"
+        sandbox="allow-scripts allow-forms"
+        src="resources/sandboxed-iframe-form-allowed.html">
+    </iframe>
+    <iframe style="width: 60px; height: 60px;"
+        sandbox="allow-scripts allow-forms"
+        src="resources/sandboxed-iframe-form-allowed.html">
+    </iframe>
+    <iframe style="width: 60px; height: 60px;"
+        sandbox="allow-scripts allow-forms"
+        src="resources/sandboxed-iframe-form-allowed.html">
+    </iframe>
+    
+    <p id='test_status'>FAIL: Script didn't run</p>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-navigation-allowed-expected.txt b/LayoutTests/fast/frames/sandboxed-iframe-navigation-allowed-expected.txt
new file mode 100644 (file)
index 0000000..ce59b35
--- /dev/null
@@ -0,0 +1,12 @@
+This test verifies that a sandboxed iframe CAN navigate both itself and a child in the frame tree. It also verifies that the sandbox attribute remains intact after a frame has been navigated, and that sandbox attributes are propagated through the frame hierarchy.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS (self.sandboxedFrame.frameWithPlugin.document.getElementById('plugin').destroyStream) == undefined is true
+PASS (self.frameWithPlugin.document.getElementById('plugin').destroyStream) != undefined is true
+PASS document.getElementById('sandboxedFrameId').sandbox is 'allow-scripts allow-same-origin'
+PASS successfullyParsed is true
+
+TEST COMPLETE
+  
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-navigation-allowed.html b/LayoutTests/fast/frames/sandboxed-iframe-navigation-allowed.html
new file mode 100644 (file)
index 0000000..494e8de
--- /dev/null
@@ -0,0 +1,60 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<script src="../js/resources/js-test-post-function.js"></script>
+<script>
+
+if (window.layoutTestController) {
+    window.layoutTestController.dumpAsText();
+    window.layoutTestController.waitUntilDone();
+}
+
+function childFrameWasNavigated()
+{
+    // Check that the child frame was unable to load a plugin, since its parent is sandboxed.
+    shouldBeTrue("(self.sandboxedFrame.frameWithPlugin.document.getElementById('plugin').destroyStream) == undefined");
+    
+    // Check a non-sandboxed frame as well, to ensure that the plugin is disabled by sandboxing
+    // and not some other failure
+    shouldBeTrue("(self.frameWithPlugin.document.getElementById('plugin').destroyStream) != undefined");
+
+    // When the child frame (grandchild of the main window) has been navigated,
+    // make the sandboxed frame navigate itself
+    self.sandboxedFrame.location.assign("javascript: top.sandboxWasNavigated();");
+}
+
+function sandboxWasNavigated()
+{
+    shouldBe("document.getElementById('sandboxedFrameId').sandbox", "'allow-scripts allow-same-origin'");
+    isSuccessfullyParsed();
+
+    if (window.layoutTestController)
+        window.layoutTestController.notifyDone();
+}
+
+</script>
+</head>
+
+<body>
+    <p id="description"></p>
+    <div id="console"></div>
+
+    <iframe sandbox="allow-scripts allow-same-origin"
+            name="sandboxedFrame"
+            id="sandboxedFrameId"
+            src="resources/sandboxed-iframe-navigation-child.html">
+    </iframe>
+
+    <iframe name="frameWithPlugin"
+            src="resources/sandboxed-iframe-plugins-frame-object.html">
+    </iframe>
+
+    <script>
+    description("This test verifies that a sandboxed iframe CAN navigate both itself and a child in the frame tree. "
+                + "It also verifies that the sandbox attribute remains intact after a frame has been navigated, "
+                + "and that sandbox attributes are propagated through the frame hierarchy.");
+    var successfullyParsed = true;
+    </script>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-navigation-parent-expected.txt b/LayoutTests/fast/frames/sandboxed-iframe-navigation-parent-expected.txt
new file mode 100644 (file)
index 0000000..48a86db
--- /dev/null
@@ -0,0 +1,8 @@
+This test verifies that a sandboxed IFrame cannot navigate an ancestor in the frame tree by assigning the location attribute.
+
+This is done by loading ten non-sandboxed IFrames, and a single sandboxed one. Expect ten frames to be navigated, but the sandboxed one to not be one of them.
+
+This test will print "PASS" on success.
+
+               
+PASS
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-navigation-parent.html b/LayoutTests/fast/frames/sandboxed-iframe-navigation-parent.html
new file mode 100644 (file)
index 0000000..6379e99
--- /dev/null
@@ -0,0 +1,68 @@
+<html>
+<head>
+<script>
+
+if (window.layoutTestController) {
+    window.layoutTestController.dumpAsText();
+    window.layoutTestController.waitUntilDone();
+}
+
+var navigatedFrames = 0;
+
+function checkResults()
+{
+    var testStatus = document.getElementById('testStatus');
+
+    if (self.navigated.location.href.indexOf('parent.html') == -1)
+        testStatus.innerHTML = 'FAIL: disallowed frame navigated';
+    else if (navigatedFrames == 10)
+        testStatus.innerHTML = 'PASS';
+    else
+        testStatus.innerHTML = 'FAIL: frames not navigated properly';
+
+    if (window.layoutTestController)
+        window.layoutTestController.notifyDone();
+}
+
+function countFrame()
+{
+    ++navigatedFrames;
+
+    if (navigatedFrames == 10)
+        checkResults();
+}
+
+</script>
+</head>
+
+<body>
+
+    <p>This test verifies that a sandboxed IFrame cannot navigate an ancestor
+    in the frame tree by assigning the location attribute.</p>
+
+    <p>This is done by loading ten non-sandboxed IFrames, and a single
+    sandboxed one. Expect ten frames to be navigated, but the sandboxed
+    one to <b>not</b> be one of them.</p>
+    
+    <p>This test will print &quot;PASS&quot; on success.</p>
+
+    <iframe src="resources/non-sandboxed-iframe-navigation.html"></iframe>
+    <iframe src="resources/non-sandboxed-iframe-navigation.html"></iframe>
+    <iframe src="resources/non-sandboxed-iframe-navigation.html"></iframe>
+    <iframe src="resources/non-sandboxed-iframe-navigation.html"></iframe>
+    <iframe src="resources/non-sandboxed-iframe-navigation.html"></iframe>
+
+    <iframe name='navigated'
+            src="resources/sandboxed-iframe-navigation-parent.html"
+    </iframe>
+
+    <iframe src="resources/non-sandboxed-iframe-navigation.html"></iframe>
+    <iframe src="resources/non-sandboxed-iframe-navigation.html"></iframe>
+    <iframe src="resources/non-sandboxed-iframe-navigation.html"></iframe>
+    <iframe src="resources/non-sandboxed-iframe-navigation.html"></iframe>
+    <iframe src="resources/non-sandboxed-iframe-navigation.html"></iframe>
+
+    <p id='testStatus'>FAIL: Script didn't run</p>
+    
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-navigation-targetlink-expected.txt b/LayoutTests/fast/frames/sandboxed-iframe-navigation-targetlink-expected.txt
new file mode 100644 (file)
index 0000000..579526f
--- /dev/null
@@ -0,0 +1,8 @@
+This test verifies that a sandboxed IFrame cannot open a link in another frame using the target attribute of a link.
+
+This is done by loading ten non-sandboxed IFrames, and a single sandboxed one. In addition each of these frames have a target frame (so, 22 frames in total). Expect ten frames to be able to open a link in their corresponding target frame, but the sandboxed one to not be one of them.
+
+This test will print "PASS" on success.
+
+                                
+PASS
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-navigation-targetlink.html b/LayoutTests/fast/frames/sandboxed-iframe-navigation-targetlink.html
new file mode 100644 (file)
index 0000000..0012edb
--- /dev/null
@@ -0,0 +1,109 @@
+<html>
+<head>
+<script>
+
+if (window.layoutTestController) {
+    window.layoutTestController.dumpAsText();
+    window.layoutTestController.waitUntilDone();
+}
+
+var navigatedFrames = 0;
+
+function checkResults()
+{
+    var testStatus = document.getElementById('testStatus');
+
+    if (self.sandboxed_target.location.href.indexOf('.html') != -1)
+        testStatus.innerHTML = 'FAIL: disallowed frame navigated';
+    else if (navigatedFrames == 10)
+        testStatus.innerHTML = 'PASS';
+    else
+        testStatus.innerHTML = 'FAIL: frames not navigated properly';
+
+    if (window.layoutTestController)
+        window.layoutTestController.notifyDone();
+}
+
+function countFrame()
+{
+    ++navigatedFrames;
+
+    if (navigatedFrames == 10)
+        checkResults();
+}
+
+</script>
+</head>
+
+<body>
+
+    <p>This test verifies that a sandboxed IFrame cannot open a link in
+    another frame using the <code>target</code> attribute of a link.</p>
+
+    <p>This is done by loading ten non-sandboxed IFrames, and a single
+    sandboxed one. In addition each of these frames have a target frame
+    (so, 22 frames in total). Expect ten frames to be able to open a link
+    in their corresponding target frame, but the sandboxed one
+    to <b>not</b> be one of them.</p>
+    
+    <p>This test will print &quot;PASS&quot; on success.</p>
+
+    <iframe src="resources/sandboxed-iframe-navigation-targetlink.html"
+            name="f1">
+    </iframe>
+    <iframe name="f1_target" src="about:blank"></iframe>
+
+    <iframe src="resources/sandboxed-iframe-navigation-targetlink.html"
+            name="f2">
+    </iframe>
+    <iframe name="f2_target" src="about:blank"></iframe>
+
+    <iframe src="resources/sandboxed-iframe-navigation-targetlink.html"
+            name="f3">
+    </iframe>
+    <iframe name="f3_target" src="about:blank"></iframe>
+
+    <iframe src="resources/sandboxed-iframe-navigation-targetlink.html"
+            name="f4">
+    </iframe>
+    <iframe name="f4_target" src="about:blank"></iframe>
+
+    <iframe src="resources/sandboxed-iframe-navigation-targetlink.html"
+            name="f5">
+    </iframe>
+    <iframe name="f5_target" src="about:blank"></iframe>
+
+    <iframe src="resources/sandboxed-iframe-navigation-targetlink.html"
+            name="sandboxed"
+            sandbox="allow-scripts allow-same-origin">
+    </iframe>
+    <iframe name="sandboxed_target" src="about:blank"></iframe>
+
+    <iframe src="resources/sandboxed-iframe-navigation-targetlink.html"
+            name="f6">
+    </iframe>
+    <iframe name="f6_target" src="about:blank"></iframe>
+
+    <iframe src="resources/sandboxed-iframe-navigation-targetlink.html"
+            name="f7">
+    </iframe>
+    <iframe name="f7_target" src="about:blank"></iframe>
+
+    <iframe src="resources/sandboxed-iframe-navigation-targetlink.html"
+            name="f8">
+    </iframe>
+    <iframe name="f8_target" src="about:blank"></iframe>
+
+    <iframe src="resources/sandboxed-iframe-navigation-targetlink.html"
+            name="f9">
+    </iframe>
+    <iframe name="f9_target" src="about:blank"></iframe>
+
+    <iframe src="resources/sandboxed-iframe-navigation-targetlink.html"
+            name="f10">
+    </iframe>
+    <iframe name="f10_target" src="about:blank"></iframe>
+
+    <p id='testStatus'>FAIL: Script didn't run</p>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-navigation-windowopen-expected.txt b/LayoutTests/fast/frames/sandboxed-iframe-navigation-windowopen-expected.txt
new file mode 100644 (file)
index 0000000..60ee02d
--- /dev/null
@@ -0,0 +1,6 @@
+Verifies that a sandboxed IFrame cannot open new windows using window.open(). Expect ten windows to be opened, but the sandboxed IFrame not to be the opener of any of them.
+
+This test will print "PASS" on success.
+
+               
+PASS
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-navigation-windowopen.html b/LayoutTests/fast/frames/sandboxed-iframe-navigation-windowopen.html
new file mode 100644 (file)
index 0000000..024f2fa
--- /dev/null
@@ -0,0 +1,72 @@
+<html>
+<head>
+<script>
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+    layoutTestController.setCanOpenWindows(true);
+}
+
+var testStatus       = "FAIL: not completed";
+var windowsOpened    = 0;
+var mainWindowLoaded = false;
+var testCompleted    = false;
+
+function updateStatus(loaded, done)
+{
+    mainWindowLoaded |= loaded;
+    testCompleted |= done;
+
+    if (mainWindowLoaded && testCompleted) {
+        document.getElementById("testStatus").innerHTML = testStatus;
+        if (testCompleted && window.layoutTestController)
+            layoutTestController.notifyDone();
+    }
+}
+
+function windowOpened(windowOpener)
+{
+    if (windowOpener == self.sandboxed) {
+        testStatus = "FAIL: sandboxed frame opened window";
+        updateStatus(false, true);
+    } else {
+        ++windowsOpened;
+        if (windowsOpened == 10 && !testCompleted) {
+            testStatus = "PASS";
+            updateStatus(false, true);
+        }
+    }
+}
+
+</script>
+</head>
+
+<body onload="updateStatus(true, false);">
+
+    <p>Verifies that a sandboxed IFrame cannot open new windows
+    using <code>window.open()</code>. Expect ten windows to be opened,
+    but the sandboxed IFrame not to be the opener of any of them.</p>
+    
+    <p>This test will print &quot;PASS&quot; on success.</p>
+
+    <iframe src="resources/sandboxed-iframe-navigation-windowopen.html"></iframe>
+    <iframe src="resources/sandboxed-iframe-navigation-windowopen.html"></iframe>
+    <iframe src="resources/sandboxed-iframe-navigation-windowopen.html"></iframe>
+    <iframe src="resources/sandboxed-iframe-navigation-windowopen.html"></iframe>
+    <iframe src="resources/sandboxed-iframe-navigation-windowopen.html"></iframe>
+
+    <iframe src="resources/sandboxed-iframe-navigation-windowopen.html"
+            sandbox="allow-scripts"
+            name="sandboxed">
+    </iframe>
+
+    <iframe src="resources/sandboxed-iframe-navigation-windowopen.html"></iframe>
+    <iframe src="resources/sandboxed-iframe-navigation-windowopen.html"></iframe>
+    <iframe src="resources/sandboxed-iframe-navigation-windowopen.html"></iframe>
+    <iframe src="resources/sandboxed-iframe-navigation-windowopen.html"></iframe>
+    <iframe src="resources/sandboxed-iframe-navigation-windowopen.html"></iframe>
+
+    <p id='testStatus'>FAIL: Script didn't run</p>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-plugins-expected.txt b/LayoutTests/fast/frames/sandboxed-iframe-plugins-expected.txt
new file mode 100644 (file)
index 0000000..15bb273
--- /dev/null
@@ -0,0 +1,17 @@
+This test verifies that sandboxing of plugins works as intended. Three tests are made, each in one sandboxed and one non-sandboxed IFrame: applets, embeds, and objects.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+NOTE: The first sub-test will fail in DumpRenderTree, since DumpRenderTree does not support applets. That sub-test must be run in Safari instead.
+
+FAIL (self.appletFrame1.document['app'].init) != undefined should be true. Was false.
+PASS (self.appletFrame2.document['app'].init) == undefined is true
+PASS (self.embedFrame1.document.getElementById('plugin').destroyStream) != undefined is true
+PASS (self.embedFrame2.document.getElementById('plugin').destroyStream) == undefined is true
+PASS (self.objectFrame1.document.getElementById('plugin').destroyStream) != undefined is true
+PASS (self.objectFrame2.document.getElementById('plugin').destroyStream) == undefined is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+         
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-plugins.html b/LayoutTests/fast/frames/sandboxed-iframe-plugins.html
new file mode 100644 (file)
index 0000000..3f40691
--- /dev/null
@@ -0,0 +1,74 @@
+<html> 
+<head> 
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<script src="../js/resources/js-test-post-function.js"></script>
+<script> 
+if (window.layoutTestController) 
+    layoutTestController.dumpAsText(); 
+window.onload = function() { 
+    shouldBeTrue("(self.appletFrame1.document['app'].init) != undefined");
+    shouldBeTrue("(self.appletFrame2.document['app'].init) == undefined");
+
+    shouldBeTrue("(self.embedFrame1.document.getElementById('plugin').destroyStream) != undefined");
+    shouldBeTrue("(self.embedFrame2.document.getElementById('plugin').destroyStream) == undefined");
+
+    shouldBeTrue("(self.objectFrame1.document.getElementById('plugin').destroyStream) != undefined");
+    shouldBeTrue("(self.objectFrame2.document.getElementById('plugin').destroyStream) == undefined");
+
+    isSuccessfullyParsed();
+} 
+</script> 
+</head> 
+<body> 
+    <p id="description"></p>
+    <p>NOTE: The first sub-test will fail in DumpRenderTree, since DumpRenderTree
+    does not support applets. That sub-test must be run in Safari instead.</p> 
+
+    <div id="console"></div>
+
+    <!-- Applets -->
+    
+    <iframe id="appletFrame1" 
+            style="width: 200px; height: 100px;" 
+            src="resources/sandboxed-iframe-plugins-frame-applet.html"> 
+    </iframe> 
+    <iframe id="appletFrame2" 
+            style="width: 200px; height: 100px;" 
+            sandbox="allow-same-origin allow-scripts" 
+            src="resources/sandboxed-iframe-plugins-frame-applet.html"> 
+    </iframe> 
+
+    <!-- Embeds -->
+    
+    <iframe id="embedFrame1"
+            style="width: 200px; height: 100px;"
+            src="resources/sandboxed-iframe-plugins-frame-embed.html">
+    </iframe>
+    <iframe id="embedFrame2"
+            style="width: 200px; height: 100px;"
+            sandbox="allow-same-origin"
+            src="resources/sandboxed-iframe-plugins-frame-embed.html">
+    </iframe>
+
+    <!-- Objects -->
+    
+    <iframe id="objectFrame1"
+            style="width: 200px; height: 100px;"
+            src="resources/sandboxed-iframe-plugins-frame-object.html">
+    </iframe>
+    <iframe id="objectFrame2"
+            style="width: 200px; height: 100px;"
+            sandbox="allow-same-origin"
+            src="resources/sandboxed-iframe-plugins-frame-object.html">
+    </iframe>
+
+    <script>
+    description("This test verifies that sandboxing of plugins works as intended. Three tests are made, each in one sandboxed and one non-sandboxed IFrame: applets, embeds, and objects.");
+    var successfullyParsed = true;
+    </script>
+</body> 
+</html> 
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-scripting-expected.txt b/LayoutTests/fast/frames/sandboxed-iframe-scripting-expected.txt
new file mode 100644 (file)
index 0000000..776a5c7
--- /dev/null
@@ -0,0 +1,11 @@
+Verify that sandboxed frames with sandbox="allow-scripts" can execute scripts, but other sandboxed frames cannot. Also verify that removing the sandbox="allow-scripts" attribute at runtime prevents new scripts from launching, but existing ones keep running.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS disallowedExecuted is 0
+PASS allowedExecuted is 2
+PASS successfullyParsed is true
+
+TEST COMPLETE
+   
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-scripting.html b/LayoutTests/fast/frames/sandboxed-iframe-scripting.html
new file mode 100644 (file)
index 0000000..225974f
--- /dev/null
@@ -0,0 +1,46 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<script src="../js/resources/js-test-post-function.js"></script>
+<script>
+if (window.layoutTestController)
+    window.layoutTestController.dumpAsText();
+
+var disallowedExecuted = 0;
+var allowedExecuted = 0;
+
+window.onload = function()
+{
+    shouldBe("disallowedExecuted", "0");
+    shouldBe("allowedExecuted", "2");
+
+    isSuccessfullyParsed();
+}
+</script>
+</head>
+
+<body>
+    <p id="description"></p>
+    <div id="console"></div>
+    <iframe sandbox="allow-same-origin allow-scripts"
+            src="javascript: ++window.top.allowedExecuted;">
+    </iframe>
+    <iframe sandbox="allow-same-origin"
+            src="javascript: ++window.top.disallowedExecuted;">
+    </iframe>
+    
+    <iframe id="frame" src="resources/sandboxed-iframe-script-dynamic.html">
+    </iframe>
+
+    <script>
+    description("Verify that sandboxed frames with sandbox=&quot;allow-scripts&quot; can execute scripts, "
+                 + "but other sandboxed frames cannot. Also verify that removing the "
+                 + "sandbox=&quot;allow-scripts&quot; attribute at runtime prevents new scripts from launching, "
+                 + "but existing ones keep running.");
+    var successfullyParsed = true;
+    </script>
+</body>
+</html>
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-storage-expected.txt b/LayoutTests/fast/frames/sandboxed-iframe-storage-expected.txt
new file mode 100644 (file)
index 0000000..9262a4a
--- /dev/null
@@ -0,0 +1,28 @@
+This test verifies that a sandboxed iframe does not have access to any session storage, local storage or database.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Most of the PASS messages appear in frames, presented by DumpRenderTree after the main window.
+
+  
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS window.openDatabase() == null is true
+PASS window.localStorage == null is true
+PASS window.sessionStorage == null is true
+
+
+--------
+Frame: '<!--framePath //<!--frame1-->-->'
+--------
+PASS window.openDatabase() != null is true
+PASS window.localStorage != null is true
+PASS window.sessionStorage != null is true
+
diff --git a/LayoutTests/fast/frames/sandboxed-iframe-storage.html b/LayoutTests/fast/frames/sandboxed-iframe-storage.html
new file mode 100644 (file)
index 0000000..f622b5d
--- /dev/null
@@ -0,0 +1,37 @@
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<script src="../js/resources/js-test-post-function.js"></script>
+<script>
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpChildFramesAsText();
+}
+
+window.onload = function() { 
+    isSuccessfullyParsed();
+} 
+
+</script>
+</head>
+<body>
+    <p id="description"></p>
+
+    <p>Most of the PASS messages appear in frames, presented by DumpRenderTree after the main window.</p>
+
+    <iframe sandbox="allow-scripts" src="resources/sandboxed-iframe-storage-disallowed.html">
+    </iframe>
+
+    <iframe src="resources/sandboxed-iframe-storage-allowed.html">
+    </iframe>
+
+    <div id="console"></div>
+
+    <script>
+    description("This test verifies that a sandboxed iframe does not have access to any session storage, local storage or database.");
+    var successfullyParsed = true;
+    </script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/resources/sandboxed-iframe-document-cookie-read-denied.html b/LayoutTests/http/tests/security/resources/sandboxed-iframe-document-cookie-read-denied.html
new file mode 100644 (file)
index 0000000..d3e74b2
--- /dev/null
@@ -0,0 +1,25 @@
+<html>
+<head>
+<script>
+
+function runTest()
+{
+    document.getElementById("testResult").innerHTML = (function() {
+        try {
+            var cookie = document.cookie;
+        }
+        catch (err) {
+            if (err.name.indexOf("SECURITY_ERR") != -1)
+                return "PASS";
+        }
+
+        return "FAIL: SECURITY_ERR not raised";
+    })();
+}
+
+</script>
+</head>
+<body onload="runTest();">
+    <p id="testResult">FAIL: Script didn't run</p>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/resources/sandboxed-iframe-modify-self.html b/LayoutTests/http/tests/security/resources/sandboxed-iframe-modify-self.html
new file mode 100644 (file)
index 0000000..9539c0a
--- /dev/null
@@ -0,0 +1,14 @@
+<html>
+<head>
+<script>
+
+// this assignment should have no effect on sandbox status
+self.sandbox = 'allow-scripts allow-same-origin hacked-via-window-object';
+
+// this should be prevented by the sandbox 'origin' flag
+if (top.document)
+    top.document.getElementById('f').sandbox = 'allow-scripts allow-same-origin hacked-via-dom';
+
+</script>
+</head>
+</html>
diff --git a/LayoutTests/http/tests/security/resources/xss-DENIED-sandboxed-iframe-attacker.html b/LayoutTests/http/tests/security/resources/xss-DENIED-sandboxed-iframe-attacker.html
new file mode 100644 (file)
index 0000000..d20a660
--- /dev/null
@@ -0,0 +1,7 @@
+<html>
+<head>
+<script>
+    top.docRef = parent.document;  // access parent's DOM tree: should not be allowed
+</script>
+</head>
+</html>
diff --git a/LayoutTests/http/tests/security/sandboxed-iframe-document-cookie-expected.txt b/LayoutTests/http/tests/security/sandboxed-iframe-document-cookie-expected.txt
new file mode 100644 (file)
index 0000000..ea17cfb
--- /dev/null
@@ -0,0 +1,8 @@
+This test checks that a SECURITY_ERR exception is raised while accessing document.domain in a sandboxed iframe (without "allow-origin" set). This test will print "PASS" on success.
+
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS
diff --git a/LayoutTests/http/tests/security/sandboxed-iframe-document-cookie.html b/LayoutTests/http/tests/security/sandboxed-iframe-document-cookie.html
new file mode 100644 (file)
index 0000000..68b1b3f
--- /dev/null
@@ -0,0 +1,25 @@
+<html>
+<head>
+
+<script>
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpChildFramesAsText();
+}
+
+</script>
+</head>
+
+<body>
+
+    <p>This test checks that a SECURITY_ERR exception is raised while accessing document.domain
+    in a sandboxed iframe (without &quot;allow-origin&quot; set). This test will print
+    &quot;PASS&quot; on success.</p>
+
+    <iframe sandbox="allow-scripts"
+            src="resources/sandboxed-iframe-document-cookie-read-denied.html">
+    </iframe>
+</body>
+
+</html>
diff --git a/LayoutTests/http/tests/security/sandboxed-iframe-modify-self-expected.txt b/LayoutTests/http/tests/security/sandboxed-iframe-modify-self-expected.txt
new file mode 100644 (file)
index 0000000..e3c40da
--- /dev/null
@@ -0,0 +1,11 @@
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/security/sandboxed-iframe-modify-self.html from frame with URL http://127.0.0.1:8000/security/resources/sandboxed-iframe-modify-self.html. Domains, protocols and ports must match.
+
+This is a "sanity" test case to verify that a sandboxed frame cannot break out of its sandbox by modifying its own sandbox attribute. Two attempts are made:
+
+First, an attempt is made to modify the sandbox attribute of the "self" object, referring to the frame's window. This should not have any effect (the attribute is associated with the iframe DOM node, not the window). No warning is expected.
+Second, an attempt is made to modify the iframe DOM object's sandbox attribute. A warning message (about cross-site scripting) is expected, and the sandbox attribute should remain intact.
+This test will print "PASS" on success.
+
+PASS
+
+
diff --git a/LayoutTests/http/tests/security/sandboxed-iframe-modify-self.html b/LayoutTests/http/tests/security/sandboxed-iframe-modify-self.html
new file mode 100644 (file)
index 0000000..41660bd
--- /dev/null
@@ -0,0 +1,42 @@
+<html>
+<head>
+<script>
+
+if (window.layoutTestController)
+    window.layoutTestController.dumpAsText();
+
+window.onload = function()
+{
+    document.getElementById("result").innerHTML = (document.getElementById("f").sandbox != "allow-scripts")
+                                                ? "FAIL: sandbox attribute modified"
+                                                : "PASS";
+}
+
+</script>
+</head>
+
+<body>
+    <p>This is a &quot;sanity&quot; test case to verify that a sandboxed 
+    frame cannot break out of its sandbox by modifying its own sandbox
+    attribute. Two attempts are made:</p>
+    
+    <ol>
+        <li>First, an attempt is made to modify the sandbox attribute of the
+        &quot;self&quot; object, referring to the frame's window. This should
+        not have any effect (the attribute is associated with the iframe DOM
+        node, not the window). No warning is expected.</li>
+        <li>Second, an attempt is made to modify the iframe DOM object's sandbox
+        attribute. A warning message (about cross-site scripting) is expected,
+        and the sandbox attribute should remain intact.</li>
+    </ol>
+    
+    <p>This test will print &quot;PASS&quot; on success.</p>
+
+    <p id="result">FAIL</p>
+
+    <iframe id="f"
+            sandbox="allow-scripts"
+            src="resources/sandboxed-iframe-modify-self.html">
+    </iframe>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/xss-DENIED-sandboxed-iframe-expected.txt b/LayoutTests/http/tests/security/xss-DENIED-sandboxed-iframe-expected.txt
new file mode 100644 (file)
index 0000000..59670ee
--- /dev/null
@@ -0,0 +1,8 @@
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/security/xss-DENIED-sandboxed-iframe.html from frame with URL http://127.0.0.1:8000/security/resources/xss-DENIED-sandboxed-iframe-attacker.html. Domains, protocols and ports must match.
+
+CONSOLE MESSAGE: line 1: Unsafe JavaScript attempt to access frame with URL http://127.0.0.1:8000/security/xss-DENIED-sandboxed-iframe.html from frame with URL http://127.0.0.1:8000/security/resources/xss-DENIED-sandboxed-iframe-attacker.html. Domains, protocols and ports must match.
+
+This test verifies that sandboxed iframe prevents cross-domain script access. It will print "PASS" on success.
+
+
+PASS: cross-domain script access disallowed from sandboxed iframe
diff --git a/LayoutTests/http/tests/security/xss-DENIED-sandboxed-iframe.html b/LayoutTests/http/tests/security/xss-DENIED-sandboxed-iframe.html
new file mode 100644 (file)
index 0000000..55aadcb
--- /dev/null
@@ -0,0 +1,29 @@
+<html>
+<script>
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+var docRef = undefined;
+
+window.onload = function()
+{
+    document.getElementById("console").innerHTML =
+        (docRef ? "FAIL: cross-domain script access allowed from sandboxed iframe"
+                : "PASS: cross-domain script access disallowed from sandboxed iframe");
+}
+
+</script>
+<body>
+
+    <p>This test verifies that sandboxed iframe prevents cross-domain
+    script access. It will print &quot;PASS&quot; on success.</p>
+
+    <iframe sandbox="allow-scripts"
+            src="http://127.0.0.1:8000/security/resources/xss-DENIED-sandboxed-iframe-attacker.html">
+    </iframe>
+    
+    <div id="console">FAIL: Script didn't run</div>
+    
+</body>
+</html>
diff --git a/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow-expected.txt b/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow-expected.txt
new file mode 100644 (file)
index 0000000..420cb74
--- /dev/null
@@ -0,0 +1,9 @@
+This test verifies that sandboxed iframe has XmlHttpRequest access to the server that accepts all domains. It will print "PASS" on success.
+
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS: Sandboxed iframe XHR access allowed.
+
diff --git a/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow.html b/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow.html
new file mode 100644 (file)
index 0000000..dc01174
--- /dev/null
@@ -0,0 +1,18 @@
+<html>
+<script>
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpChildFramesAsText();
+}
+
+</script>
+<body>
+    <p>This test verifies that sandboxed iframe has XmlHttpRequest access
+    to the server that accepts all domains. It will print &quot;PASS&quot; on success.</p>
+    
+    <iframe sandbox="allow-scripts" src="http://127.0.0.1:8000/xmlhttprequest/resources/access-control-sandboxed-iframe-allow-iframe.html" style="width: 500px;">
+    </iframe> 
+    
+</body> 
+</html> 
diff --git a/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-expected.txt b/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-expected.txt
new file mode 100644 (file)
index 0000000..1d760cc
--- /dev/null
@@ -0,0 +1,8 @@
+This test verifies that sandboxed iframe does not have XmlHttpRequest access to its server. It will print "PASS" on success.
+
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS: Exception thrown. Sandboxed iframe XHR access was denied in 'send'. [NETWORK_ERR: XMLHttpRequest Exception 101].
diff --git a/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard-expected.txt b/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard-expected.txt
new file mode 100644 (file)
index 0000000..484013b
--- /dev/null
@@ -0,0 +1,10 @@
+This test verifies that sandboxed iframe does not have XmlHttpRequest access to its server with "Access-Control-Allow-Origin" set to its own origin (127.0.0.1).
+
+This test will print "PASS" on success.
+
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASS: Exception thrown. Sandboxed iframe XHR access was denied in 'send'. [NETWORK_ERR: XMLHttpRequest Exception 101].
diff --git a/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard.html b/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard.html
new file mode 100644 (file)
index 0000000..fc48dc8
--- /dev/null
@@ -0,0 +1,22 @@
+<html>
+<script>
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpChildFramesAsText();
+}
+
+</script>
+<body>
+
+    <p>This test verifies that sandboxed iframe does not have XmlHttpRequest access to
+    its server with "Access-Control-Allow-Origin" set to its own origin (127.0.0.1).</p>
+    
+    <p>This test will print &quot;PASS&quot; on success.</p>
+
+    <iframe sandbox="allow-scripts"
+            src="http://127.0.0.1:8000/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard-iframe.html" style="width: 500px;">
+    </iframe>
+    
+</body>
+</html>
diff --git a/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied.html b/LayoutTests/http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied.html
new file mode 100644 (file)
index 0000000..cd1a7d0
--- /dev/null
@@ -0,0 +1,19 @@
+<html> 
+<script>
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpChildFramesAsText();
+}
+
+</script>
+
+<body> 
+    <p>This test verifies that sandboxed iframe does not have XmlHttpRequest access
+    to its server. It will print &quot;PASS&quot; on success.</p>
+    
+    <iframe sandbox="allow-scripts"
+            src="http://127.0.0.1:8000/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-iframe.html" style="width: 500px;">
+    </iframe> 
+</body> 
+</html> 
diff --git a/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow-iframe.html b/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow-iframe.html
new file mode 100644 (file)
index 0000000..383e7cb
--- /dev/null
@@ -0,0 +1,25 @@
+<html> 
+<body> 
+<pre id='console'></pre> 
+<script type="text/javascript"> 
+
+document.getElementById('console').innerHTML = (function() { 
+    var xhr = new XMLHttpRequest; 
+    try { 
+        xhr.open("GET", "http://127.0.0.1:8000/xmlhttprequest/resources/access-control-sandboxed-iframe-allow.cgi", false); 
+    } catch(e) { 
+        return "FAIL: Exception thrown. Sandboxed iframe XHR access is not allowed in 'open'. [" + e.message + "]."; 
+    } 
+    try { 
+        xhr.send(); 
+    } catch(e) { 
+        return "FAIL: Exception thrown. Sandboxed iframe XHR access is not allowed in 'send'. [" + e.message + "]."; 
+    } 
+    return xhr.responseText; 
+})(); 
+</script> 
+</body> 
+</html>
diff --git a/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow.cgi b/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-allow.cgi
new file mode 100755 (executable)
index 0000000..833376f
--- /dev/null
@@ -0,0 +1,8 @@
+#!/usr/bin/perl -wT
+use strict;
+
+print "Content-Type: text/plain\n";
+print "Access-Control-Allow-Credentials: true\n";
+print "Access-Control-Allow-Origin: *\n\n";
+
+print "PASS: Sandboxed iframe XHR access allowed.\n";
diff --git a/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-iframe.html b/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-iframe.html
new file mode 100644 (file)
index 0000000..bf5a23e
--- /dev/null
@@ -0,0 +1,27 @@
+<html> 
+<body> 
+<pre id='console'></pre> 
+<script type="text/javascript"> 
+
+document.getElementById('console').innerHTML = (function() {
+    var xhr = new XMLHttpRequest; 
+    try { 
+        xhr.open("GET", "http://127.0.0.1:8000/xmlhttprequest/resources/access-control-sandboxed-iframe-denied.cgi", false); 
+    } catch(e) { 
+        return "FAIL: Exception thrown. Sandboxed iframe XHR access is not allowed in 'open'. [" + e.message + "]."; 
+    } 
+    try { 
+        xhr.send(); 
+    } catch(e) { 
+        return "PASS: Exception thrown. Sandboxed iframe XHR access was denied in 'send'. [" + e.message + "]."; 
+    }
+    return xhr.responseText; 
+})();
+  
+</script> 
+</body> 
+</html>
diff --git a/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard-iframe.html b/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard-iframe.html
new file mode 100644 (file)
index 0000000..a0f07c0
--- /dev/null
@@ -0,0 +1,26 @@
+<html>
+<body>
+<pre id='console'></pre>
+<script type="text/javascript">
+
+document.getElementById('console').innerHTML = (function() {
+    var xhr = new XMLHttpRequest;
+
+    try {
+        xhr.open("GET", "http://127.0.0.1:8000/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard.cgi", false);
+    } catch(e) {
+        return "FAIL: Exception thrown. Sandboxed iframe XHR access is not allowed in 'open'. [" + e.message + "].";
+    }
+
+    try {
+        xhr.send();
+    } catch(e) {
+        return "PASS: Exception thrown. Sandboxed iframe XHR access was denied in 'send'. [" + e.message + "].";
+    }
+
+    return xhr.responseText;
+})();
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard.cgi b/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied-without-wildcard.cgi
new file mode 100755 (executable)
index 0000000..96e6169
--- /dev/null
@@ -0,0 +1,8 @@
+#!/usr/bin/perl -wT
+use strict;
+
+print "Content-Type: text/plain\n";
+print "Access-Control-Allow-Credentials: true\n";
+print "Access-Control-Allow-Origin: http://127.0.0.1:8000\n\n";
+
+print "FAIL: Sandboxed iframe XHR access allowed.\n";
diff --git a/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied.cgi b/LayoutTests/http/tests/xmlhttprequest/resources/access-control-sandboxed-iframe-denied.cgi
new file mode 100755 (executable)
index 0000000..c59c413
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/perl -wT
+use strict;
+
+print "Content-Type: text/plain\n\n";
+
+print "FAIL: Sandboxed iframe XHR access allowed.\n";
index bf01a2a..774493a 100644 (file)
@@ -1,3 +1,88 @@
+2009-12-01  Patrik Persson  <patrik.j.persson@ericsson.com>
+
+        Reviewed by Darin Adler.
+
+        Implement HTML5 sandbox attribute for iframes.
+        http://www.w3.org/TR/html5/text-level-semantics.html#attr-iframe-sandbox
+        https://bugs.webkit.org/show_bug.cgi?id=21288
+
+        Tests: fast/frames/sandboxed-iframe-attribute-parsing.html
+               fast/frames/sandboxed-iframe-forms.html
+               fast/frames/sandboxed-iframe-navigation-allowed.html
+               fast/frames/sandboxed-iframe-navigation-parent.html
+               fast/frames/sandboxed-iframe-navigation-targetlink.html
+               fast/frames/sandboxed-iframe-navigation-windowopen.html
+               fast/frames/sandboxed-iframe-plugins.html
+               fast/frames/sandboxed-iframe-scripting.html
+               fast/frames/sandboxed-iframe-storage.html
+               http/tests/security/sandboxed-iframe-document-cookie.html
+               http/tests/security/sandboxed-iframe-modify-self.html
+               http/tests/security/xss-DENIED-sandboxed-iframe.html
+               http/tests/xmlhttprequest/access-control-sandboxed-iframe-allow.html
+               http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied-without-wildcard.html
+               http/tests/xmlhttprequest/access-control-sandboxed-iframe-denied.html
+
+        * bindings/js/JSDOMWindowCustom.cpp: sandboxing navigation
+        (WebCore::createWindow):
+        * bindings/js/ScriptController.cpp: sandboxing scripts
+        (WebCore::ScriptController::isEnabled):
+        * dom/Document.cpp:
+        (WebCore::Document::processHttpEquiv):
+        (WebCore::Document::cookie): raise exception when accessed from sandbox
+        (WebCore::Document::setCookie): raise exception when accessed from sandbox
+        (WebCore::Document::initSecurityContext): updae sandbox status
+        (WebCore::Document::updateSandboxFlags):
+        * dom/Document.h:
+        * dom/Document.idl:
+        * html/HTMLAppletElement.cpp: sandboxing applets
+        (WebCore::HTMLAppletElement::createRenderer):
+        (WebCore::HTMLAppletElement::renderWidgetForJSBindings):
+        (WebCore::HTMLAppletElement::canEmbedJava):
+        * html/HTMLAppletElement.h:
+        * html/HTMLAttributeNames.in:
+        * html/HTMLFrameOwnerElement.cpp: management of sandbox flags as stated in attribute
+        (WebCore::HTMLFrameOwnerElement::HTMLFrameOwnerElement):
+        (WebCore::HTMLFrameOwnerElement::setSandboxFlags):
+        * html/HTMLFrameOwnerElement.h:
+        (WebCore::HTMLFrameOwnerElement::sandboxFlags):
+        * html/HTMLIFrameElement.cpp: sandbox attribute parsing
+        (WebCore::parseSandboxAttribute):
+        (WebCore::HTMLIFrameElement::parseMappedAttribute):
+        * html/HTMLIFrameElement.idl:
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::getCookies):
+        * loader/CrossOriginAccessControl.cpp:
+        (WebCore::passesAccessControlCheck):
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::FrameLoader):
+        (WebCore::FrameLoader::init):
+        (WebCore::FrameLoader::submitForm): sandboxing forms
+        (WebCore::FrameLoader::requestObject): sandboxing plugins
+        (WebCore::FrameLoader::shouldAllowNavigation): sandboxing navigation
+        (WebCore::FrameLoader::updateSandboxFlags): propagation of sandbox flags
+        * loader/FrameLoader.h:
+        (WebCore::FrameLoader::ownerElementSandboxFlagsChanged):
+        (WebCore::FrameLoader::isSandboxed):
+        (WebCore::FrameLoader::sandboxFlags):
+        * loader/FrameLoaderTypes.h:
+        (WebCore::):
+        * page/DOMWindow.cpp: disable storage and databases in sandboxed frames
+        (WebCore::DOMWindow::sessionStorage):
+        (WebCore::DOMWindow::localStorage):
+        (WebCore::DOMWindow::openDatabase):
+        * page/SecurityOrigin.cpp: added sandboxing status
+        (WebCore::SecurityOrigin::SecurityOrigin):
+        (WebCore::SecurityOrigin::canAccess):
+        (WebCore::SecurityOrigin::canRequest):
+        (WebCore::SecurityOrigin::toString):
+        * page/SecurityOrigin.h:
+        (WebCore::SecurityOrigin::setSandboxFlags):
+        (WebCore::SecurityOrigin::isSandboxed):
+        (WebCore::SecurityOrigin::canAccessDatabase):
+        (WebCore::SecurityOrigin::canAccessStorage):
+        * websockets/WebSocketChannel.cpp:
+        (WebCore::WebSocketChannel::didReceiveData):
+
 2009-12-01  Chris Fleizach  <cfleizach@apple.com>
 
         Reviewed by David Kilzer.
index 8015aca..8ba7b91 100644 (file)
@@ -744,6 +744,10 @@ static Frame* createWindow(ExecState* exec, Frame* lexicalFrame, Frame* dynamicF
     ASSERT(lexicalFrame);
     ASSERT(dynamicFrame);
 
+    // Sandboxed iframes cannot open new auxiliary browsing contexts.
+    if (lexicalFrame && lexicalFrame->loader()->isSandboxed(SandboxNavigation))
+        return 0;
+
     ResourceRequest request;
 
     // For whatever reason, Firefox uses the dynamicGlobalObject to determine
index c0531c3..3c440db 100644 (file)
@@ -289,7 +289,7 @@ bool ScriptController::anyPageIsProcessingUserGesture() const
 bool ScriptController::isEnabled()
 {
     Settings* settings = m_frame->settings();
-    return m_frame->loader()->client()->allowJavaScript(settings && settings->isJavaScriptEnabled());
+    return m_frame->loader()->client()->allowJavaScript(settings && settings->isJavaScriptEnabled() && !m_frame->loader()->isSandboxed(SandboxScripts));
 }
 
 void ScriptController::attachDebugger(JSC::Debugger* debugger)
index edf50c1..48683fa 100644 (file)
@@ -2181,8 +2181,10 @@ void Document::processHttpEquiv(const String& equiv, const String& content)
         }
     } else if (equalIgnoringCase(equiv, "set-cookie")) {
         // FIXME: make setCookie work on XML documents too; e.g. in case of <html:meta .....>
-        if (isHTMLDocument())
-            static_cast<HTMLDocument*>(this)->setCookie(content);
+        if (isHTMLDocument()) {
+            ExceptionCode ec; // Exception (for sandboxed documents) ignored.
+            static_cast<HTMLDocument*>(this)->setCookie(content, ec);
+        }
     } else if (equalIgnoringCase(equiv, "content-language"))
         setContentLanguage(content);
     else if (equalIgnoringCase(equiv, "x-dns-prefetch-control"))
@@ -3000,11 +3002,20 @@ Element* Document::ownerElement() const
     return frame()->ownerElement();
 }
 
-String Document::cookie() const
+String Document::cookie(ExceptionCode& ec) const
 {
     if (page() && !page()->cookieEnabled())
         return String();
 
+    // FIXME: The HTML5 DOM spec states that this attribute can raise an
+    // INVALID_STATE_ERR exception on getting if the Document has no
+    // browsing context.
+
+    if (securityOrigin()->isSandboxed(SandboxOrigin)) {
+        ec = SECURITY_ERR;
+        return String();
+    }
+
     KURL cookieURL = this->cookieURL();
     if (cookieURL.isEmpty())
         return String();
@@ -3012,11 +3023,20 @@ String Document::cookie() const
     return cookies(this, cookieURL);
 }
 
-void Document::setCookie(const String& value)
+void Document::setCookie(const String& value, ExceptionCode& ec)
 {
     if (page() && !page()->cookieEnabled())
         return;
 
+    // FIXME: The HTML5 DOM spec states that this attribute can raise an
+    // INVALID_STATE_ERR exception on setting if the Document has no
+    // browsing context.
+
+    if (securityOrigin()->isSandboxed(SandboxOrigin)) {
+        ec = SECURITY_ERR;
+        return;
+    }
+
     KURL cookieURL = this->cookieURL();
     if (cookieURL.isEmpty())
         return;
@@ -4265,6 +4285,8 @@ void Document::initSecurityContext()
     m_cookieURL = url;
     ScriptExecutionContext::setSecurityOrigin(SecurityOrigin::create(url));
 
+    updateSandboxFlags();
     if (SecurityOrigin::allowSubstituteDataAccessToLocal()) {
         // If this document was loaded with substituteData, then the document can
         // load local resources.  See https://bugs.webkit.org/show_bug.cgi?id=16756
@@ -4315,6 +4337,12 @@ void Document::setSecurityOrigin(SecurityOrigin* securityOrigin)
     initDNSPrefetch();
 }
 
+void Document::updateSandboxFlags()
+{
+    if (m_frame && securityOrigin())
+        securityOrigin()->setSandboxFlags(m_frame->loader()->sandboxFlags());
+}
+
 void Document::updateFocusAppearanceSoon()
 {
     if (!m_updateFocusAppearanceTimer.isActive())
index e5b984c..3aee2d6 100644 (file)
@@ -675,8 +675,8 @@ public:
     void setTitle(const String&, Element* titleElement = 0);
     void removeTitle(Element* titleElement);
 
-    String cookie() const;
-    void setCookie(const String&);
+    String cookie(ExceptionCode&) const;
+    void setCookie(const String&, ExceptionCode&);
 
     String referrer() const;
 
@@ -887,6 +887,8 @@ public:
     //       that already contains content.
     void setSecurityOrigin(SecurityOrigin*);
 
+    void updateSandboxFlags(); // Set sandbox flags as determined by the frame.
+
     bool processingLoadEvent() const { return m_processingLoadEvent; }
 
 #if ENABLE(DATABASE)
index 76a4edb..210f5ff 100644 (file)
@@ -162,10 +162,9 @@ module core {
 #endif
         readonly attribute DOMString URL;
 
-        // FIXME: the DOM spec states that this attribute can 
-        // raise an exception on setting.
                  attribute [ConvertNullToNullString] DOMString cookie
-                     /*setter raises (DOMException)*/;
+                     setter raises (DOMException),
+                     getter raises (DOMException);
 
         // FIXME: the DOM spec does NOT have this attribute
         // raising an exception.
index 46045d6..f67e9dc 100644 (file)
@@ -28,6 +28,7 @@
 #include "HTMLNames.h"
 #include "MappedAttribute.h"
 #include "RenderApplet.h"
+#include "SecurityOrigin.h"
 #include "Settings.h"
 
 namespace WebCore {
@@ -108,9 +109,7 @@ bool HTMLAppletElement::rendererIsNeeded(RenderStyle* style)
 
 RenderObject* HTMLAppletElement::createRenderer(RenderArena*, RenderStyle* style)
 {
-    Settings* settings = document()->settings();
-
-    if (settings && settings->isJavaEnabled()) {
+    if (canEmbedJava()) {
         HashMap<String, String> args;
 
         args.set("code", getAttribute(codeAttr));
@@ -142,8 +141,7 @@ RenderObject* HTMLAppletElement::createRenderer(RenderArena*, RenderStyle* style
 
 RenderWidget* HTMLAppletElement::renderWidgetForJSBindings() const
 {
-    Settings* settings = document()->settings();
-    if (!settings || !settings->isJavaEnabled())
+    if (!canEmbedJava())
         return 0;
 
     RenderApplet* applet = toRenderApplet(renderer());
@@ -153,6 +151,15 @@ RenderWidget* HTMLAppletElement::renderWidgetForJSBindings() const
     return applet;
 }
 
+bool HTMLAppletElement::canEmbedJava() const
+{
+    if (document()->securityOrigin()->isSandboxed(SandboxPlugins))
+        return false;
+
+    Settings* settings = document()->settings();
+    return settings && settings->isJavaEnabled();
+}
+
 void HTMLAppletElement::finishParsingChildren()
 {
     // The parser just reached </applet>, so all the params are available now.
index baaab38..a53bd5c 100644 (file)
@@ -51,6 +51,7 @@ private:
     virtual RenderWidget* renderWidgetForJSBindings() const;
 
     void setupApplet() const;
+    bool canEmbedJava() const;
 
     virtual void insertedIntoDocument();
     virtual void removedFromDocument();
index 77164a5..696f4e0 100644 (file)
@@ -222,6 +222,7 @@ role
 rows
 rowspan
 rules
+sandbox
 scheme
 scope
 scrollamount
index 84958c2..7598da2 100644 (file)
@@ -35,6 +35,7 @@ namespace WebCore {
 HTMLFrameOwnerElement::HTMLFrameOwnerElement(const QualifiedName& tagName, Document* document)
     : HTMLElement(tagName, document, CreateElement)
     , m_contentFrame(0)
+    , m_sandboxFlags(SandboxNone)
 {
 }
 
@@ -64,6 +65,17 @@ DOMWindow* HTMLFrameOwnerElement::contentWindow() const
     return m_contentFrame ? m_contentFrame->domWindow() : 0;
 }
 
+void HTMLFrameOwnerElement::setSandboxFlags(SandboxFlags flags)
+{
+    if (m_sandboxFlags == flags)
+        return;
+
+    m_sandboxFlags = flags;
+    
+    if (Frame* frame = contentFrame())
+        frame->loader()->ownerElementSandboxFlagsChanged();
+}
+
 #if ENABLE(SVG)
 SVGDocument* HTMLFrameOwnerElement::getSVGDocument(ExceptionCode& ec) const
 {
index 1437e2c..308a100 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef HTMLFrameOwnerElement_h
 #define HTMLFrameOwnerElement_h
 
+#include "FrameLoaderTypes.h"
 #include "HTMLElement.h"
 
 namespace WebCore {
@@ -46,9 +47,13 @@ public:
 
     virtual ScrollbarMode scrollingMode() const { return ScrollbarAuto; }
 
+    SandboxFlags sandboxFlags() const { return m_sandboxFlags; }
+    
 protected:
     HTMLFrameOwnerElement(const QualifiedName& tagName, Document*);
 
+    void setSandboxFlags(SandboxFlags);
+    
 private:
     friend class Frame;
 
@@ -58,6 +63,7 @@ private:
     virtual void willRemove();
 
     Frame* m_contentFrame;
+    SandboxFlags m_sandboxFlags;
 };
 
 } // namespace WebCore
index cae9b8d..a2f287e 100644 (file)
@@ -4,6 +4,7 @@
  *           (C) 2000 Simon Hausmann (hausmann@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
  * Copyright (C) 2004, 2006, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Ericsson AB. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -66,6 +67,40 @@ bool HTMLIFrameElement::mapToEntry(const QualifiedName& attrName, MappedAttribut
     return HTMLFrameElementBase::mapToEntry(attrName, result);
 }
 
+static SandboxFlags parseSandboxAttribute(MappedAttribute* attribute)
+{
+    if (attribute->isNull())
+        return SandboxNone;
+
+    // Parse the unordered set of unique space-separated tokens.
+    SandboxFlags flags = SandboxAll;
+    const UChar* characters = attribute->value().characters();
+    unsigned length = attribute->value().length();
+    unsigned start = 0;
+    while (true) {
+        while (start < length && isASCIISpace(characters[start]))
+            ++start;
+        if (start >= length)
+            break;
+        unsigned end = start + 1;
+        while (end < length && !isASCIISpace(characters[end]))
+            ++end;
+
+        // Turn off the corresponding sandbox flag if it's set as "allowed".
+        String sandboxToken = String(characters + start, end - start);
+        if (equalIgnoringCase(sandboxToken, "allow-same-origin"))
+            flags &= ~SandboxOrigin;
+        else if (equalIgnoringCase(sandboxToken, "allow-forms"))
+            flags &= ~SandboxForms;
+        else if (equalIgnoringCase(sandboxToken, "allow-scripts"))
+            flags &= ~SandboxScripts;
+
+        start = end + 1;
+    }
+    
+    return flags;
+}
+
 void HTMLIFrameElement::parseMappedAttribute(MappedAttribute* attr)
 {
     if (attr->name() == widthAttr)
@@ -88,7 +123,9 @@ void HTMLIFrameElement::parseMappedAttribute(MappedAttribute* attr)
         if (!attr->isNull() && !attr->value().toInt())
             // Add a rule that nulls out our border width.
             addCSSLength(attr, CSSPropertyBorderWidth, "0");
-    } else
+    } else if (attr->name() == sandboxAttr)
+        setSandboxFlags(parseSandboxAttribute(attr));
+    else
         HTMLFrameElementBase::parseMappedAttribute(attr);
 }
 
index e288b54..dad8416 100644 (file)
@@ -33,6 +33,7 @@ module html {
                  attribute [ConvertNullToNullString, Reflect=marginheight] DOMString       marginHeight;
                  attribute [ConvertNullToNullString, Reflect=marginwidth] DOMString       marginWidth;
                  attribute [ConvertNullToNullString, Reflect] DOMString       name;
+                 attribute [ConvertNullToNullString, Reflect] DOMString       sandbox;
                  attribute [ConvertNullToNullString, Reflect] DOMString       scrolling;
                  attribute [ConvertNullToNullString, CustomSetter, Reflect] DOMString       src;
                  attribute [ConvertNullToNullString, Reflect] DOMString       width;
index a88a299..643fc51 100644 (file)
@@ -1203,10 +1203,14 @@ void InspectorController::getCookies(long callId, const String& host)
             Vector<Cookie> docCookiesList;
             rawCookiesImplemented = getRawCookies(document, document->cookieURL(), docCookiesList);
             
-            if (!rawCookiesImplemented)
-                // FIXME:We need duplication checking for the String representation of cookies.
-                stringCookiesList += document->cookie();
-            else {
+            if (!rawCookiesImplemented) {
+                // FIXME: We need duplication checking for the String representation of cookies.
+                ExceptionCode ec = 0;
+                stringCookiesList += document->cookie(ec);
+                // Exceptions are thrown by cookie() in sandboxed frames. That won't happen here
+                // because "document" is the document of the main frame of the page.
+                ASSERT(!ec);
+            } else {
                 int cookiesSize = docCookiesList.size();
                 for (int i = 0; i < cookiesSize; i++) {
                     if (!rawCookiesList.contains(docCookiesList[i]))
index f0f8b6a..7a21280 100644 (file)
@@ -100,6 +100,10 @@ bool passesAccessControlCheck(const ResourceResponse& response, bool includeCred
     if (accessControlOriginString == "*" && !includeCredentials)
         return true;
 
+    // A sandboxed frame has a unique origin (for same-origin purposes).
+    if (securityOrigin->isSandboxed(SandboxOrigin))
+        return false;
+
     RefPtr<SecurityOrigin> accessControlOrigin = SecurityOrigin::createFromString(accessControlOriginString);
     if (!accessControlOrigin->isSameSchemeHostPort(securityOrigin))
         return false;
index 3745cd1..52453c6 100644 (file)
@@ -196,6 +196,7 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)
     , m_didPerformFirstNavigation(false)
     , m_loadingFromCachedPage(false)
     , m_suppressOpenerInNewFrame(false)
+    , m_sandboxFlags(SandboxAll)
 #ifndef NDEBUG
     , m_didDispatchDidCommitLoad(false)
 #endif
@@ -228,6 +229,9 @@ void FrameLoader::init()
     m_frame->document()->cancelParsing();
     m_creatingInitialEmptyDocument = false;
     m_didCallImplicitClose = true;
+
+    // Propagate sandbox attributes to this Frameloader and its descendants.
+    updateSandboxFlags();
 }
 
 void FrameLoader::setDefersLoading(bool defers)
@@ -438,6 +442,9 @@ void FrameLoader::submitForm(const char* action, const String& url, PassRefPtr<F
     if (u.isEmpty())
         return;
 
+    if (isSandboxed(SandboxForms))
+        return;
+
     if (protocolIsJavaScript(u)) {
         m_isExecutingJavaScriptFormAction = true;
         m_frame->script()->executeIfJavaScriptURL(u, false, false);
@@ -1255,6 +1262,8 @@ bool FrameLoader::requestObject(RenderPart* renderer, const String& url, const A
         if (!settings || !settings->arePluginsEnabled() || 
             (!settings->isJavaEnabled() && MIMETypeRegistry::isJavaAppletMIMEType(mimeType)))
             return false;
+        if (isSandboxed(SandboxPlugins))
+            return false;
         return loadPlugin(renderer, completedURL, mimeType, paramNames, paramValues, useFallback);
     }
 
@@ -2197,6 +2206,10 @@ bool FrameLoader::shouldAllowNavigation(Frame* targetFrame) const
     if (m_frame == targetFrame)
         return true;
 
+    // A sandboxed frame can only navigate itself and its descendants.
+    if (isSandboxed(SandboxNavigation) && !targetFrame->tree()->isDescendantOf(m_frame))
+        return false;
+
     // Let a frame navigate the top-level window that contains it.  This is
     // important to allow because it lets a site "frame-bust" (escape from a
     // frame created by another web site).
@@ -3905,6 +3918,25 @@ void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
 #endif
 }
 
+void FrameLoader::updateSandboxFlags()
+{
+    SandboxFlags flags = SandboxNone;
+    if (Frame* parentFrame = m_frame->tree()->parent())
+        flags |= parentFrame->loader()->sandboxFlags();
+    if (HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement())
+        flags |= ownerElement->sandboxFlags();
+
+    if (m_sandboxFlags == flags)
+        return;
+        
+    m_sandboxFlags = flags;
+
+    m_frame->document()->updateSandboxFlags();
+
+    for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
+        child->loader()->updateSandboxFlags();
+ }
+
 PassRefPtr<Widget> FrameLoader::createJavaAppletWidget(const IntSize& size, HTMLAppletElement* element, const HashMap<String, String>& args)
 {
     String baseURLString;
index 216bc53..6c676b9 100644 (file)
@@ -251,6 +251,11 @@ public:
     void dispatchDidClearWindowObjectsInAllWorlds();
     void dispatchDocumentElementAvailable();
 
+    void ownerElementSandboxFlagsChanged() { updateSandboxFlags(); }
+    
+    bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; }
+    SandboxFlags sandboxFlags() const { return m_sandboxFlags; }
+
     // Mixed content related functions.
     static bool isMixedContent(SecurityOrigin* context, const KURL&);
     void checkIfDisplayInsecureContent(SecurityOrigin* context, const KURL&);
@@ -435,6 +440,8 @@ private:
 
     bool shouldTreatURLAsSameAsCurrent(const KURL&) const;
 
+    void updateSandboxFlags();
+    
     Frame* m_frame;
     FrameLoaderClient* m_client;
 
@@ -506,6 +513,8 @@ private:
     bool m_loadingFromCachedPage;
     bool m_suppressOpenerInNewFrame;
     
+    SandboxFlags m_sandboxFlags;
+
 #ifndef NDEBUG
     bool m_didDispatchDidCommitLoad;
 #endif
index e7d51c7..d71263b 100644 (file)
@@ -92,6 +92,18 @@ namespace WebCore {
         SendReferrer,
         NoReferrer
     };
+    
+    enum SandboxFlag {
+        SandboxNone = 0,
+        SandboxNavigation = 1,
+        SandboxPlugins = 1 << 1,
+        SandboxOrigin = 1 << 2,
+        SandboxForms = 1 << 3,
+        SandboxScripts = 1 << 4,
+        SandboxAll = -1 // Mask with all bits set to 1.
+    };
+
+    typedef unsigned SandboxFlags;
 }
 
 #endif
index 58f54bd..8bb70e0 100644 (file)
@@ -569,6 +569,9 @@ Storage* DOMWindow::sessionStorage() const
     Document* document = this->document();
     if (!document)
         return 0;
+    
+    if (!document->securityOrigin()->canAccessStorage())
+        return 0;
 
     Page* page = document->page();
     if (!page)
@@ -591,6 +594,9 @@ Storage* DOMWindow::localStorage() const
     Document* document = this->document();
     if (!document)
         return 0;
+    
+    if (!document->securityOrigin()->canAccessStorage())
+        return 0;
         
     Page* page = document->page();
     if (!page)
@@ -1107,13 +1113,15 @@ PassRefPtr<Database> DOMWindow::openDatabase(const String& name, const String& v
     if (!m_frame)
         return 0;
 
-    Document* doc = m_frame->document();
+    Document* document = m_frame->document();
+    if (!document->securityOrigin()->canAccessDatabase())
+        return 0;
 
     Settings* settings = m_frame->settings();
     if (!settings || !settings->databasesEnabled())
         return 0;
 
-    return Database::openDatabase(doc, name, version, displayName, estimatedSize, ec);
+    return Database::openDatabase(document, name, version, displayName, estimatedSize, ec);
 }
 #endif
 
index b625fba..9a413b1 100644 (file)
@@ -95,6 +95,7 @@ SecurityOrigin::SecurityOrigin(const KURL& url)
     : m_protocol(url.protocol().isNull() ? "" : url.protocol().lower())
     , m_host(url.host().isNull() ? "" : url.host().lower())
     , m_port(url.port())
+    , m_sandboxFlags(SandboxNone)
     , m_noAccess(false)
     , m_universalAccess(false)
     , m_domainWasSetInDOM(false)
@@ -127,6 +128,7 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other)
     , m_host(other->m_host.threadsafeCopy())
     , m_domain(other->m_domain.threadsafeCopy())
     , m_port(other->m_port)
+    , m_sandboxFlags(other->m_sandboxFlags)
     , m_noAccess(other->m_noAccess)
     , m_universalAccess(other->m_universalAccess)
     , m_domainWasSetInDOM(other->m_domainWasSetInDOM)
@@ -167,7 +169,7 @@ bool SecurityOrigin::canAccess(const SecurityOrigin* other) const
     if (m_universalAccess)
         return true;
 
-    if (m_noAccess || other->m_noAccess)
+    if (m_noAccess || other->m_noAccess || isSandboxed(SandboxOrigin) || other->isSandboxed(SandboxOrigin))
         return false;
 
     // Here are two cases where we should permit access:
@@ -208,7 +210,7 @@ bool SecurityOrigin::canRequest(const KURL& url) const
     if (m_universalAccess)
         return true;
 
-    if (m_noAccess)
+    if (m_noAccess || isSandboxed(SandboxOrigin))
         return false;
 
     RefPtr<SecurityOrigin> targetOrigin = SecurityOrigin::create(url);
@@ -296,7 +298,7 @@ String SecurityOrigin::toString() const
     if (isEmpty())
         return "null";
 
-    if (m_noAccess)
+    if (m_noAccess || isSandboxed(SandboxOrigin))
         return "null";
 
     if (m_protocol == "file")
index 7c32f03..bf3221f 100644 (file)
@@ -34,6 +34,7 @@
 #include <wtf/PassRefPtr.h>
 #include <wtf/Threading.h>
 
+#include "FrameLoaderTypes.h"
 #include "PlatformString.h"
 #include "StringHash.h"
 
@@ -110,6 +111,13 @@ namespace WebCore {
         // WARNING: This is an extremely powerful ability.  Use with caution!
         void grantUniversalAccess();
 
+        // Sandboxing status as determined by the frame.
+        void setSandboxFlags(SandboxFlags flags) { m_sandboxFlags = flags; }
+        bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; }
+
+        bool canAccessDatabase() const { return !isSandboxed(SandboxOrigin); }
+        bool canAccessStorage() const { return !isSandboxed(SandboxOrigin); }
+
         bool isSecureTransitionTo(const KURL&) const;
 
         // The local SecurityOrigin is the most privileged SecurityOrigin.
@@ -181,6 +189,7 @@ namespace WebCore {
         String m_host;
         String m_domain;
         unsigned short m_port;
+        SandboxFlags m_sandboxFlags;
         bool m_noAccess;
         bool m_universalAccess;
         bool m_domainWasSetInDOM;
index a110746..2dde770 100644 (file)
@@ -159,8 +159,10 @@ void WebSocketChannel::didReceiveData(SocketStreamHandle* handle, const char* da
             if (!m_handshake.serverSetCookie().isEmpty()) {
                 if (m_context->isDocument()) {
                     Document* document = static_cast<Document*>(m_context);
-                    if (cookiesEnabled(document))
-                        document->setCookie(m_handshake.serverSetCookie());
+                    if (cookiesEnabled(document)) {
+                        ExceptionCode ec; // Exception (for sandboxed documents) ignored.
+                        document->setCookie(m_handshake.serverSetCookie(), ec);
+                    }
                 }
             }
             // FIXME: handle set-cookie2.