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 4257e919bcdf34a3f2d9daed7e8895e07ceda53d..ad115708e11446b0e29d00b82710f320599549ef 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 bf01a2aacd1b3a5d262bfe3aeea4e2e357695b45..774493a16d7d53af4d81564942295830906e7d75 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 8015aca31c6e4b4910184b206baabc0c81b0cc13..8ba7b912e8d0c6ca23890efafe5d670d0c8a400b 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 c0531c3234161d51fae739157bc19cbe51be3628..3c440db1456400d4786278ba58fa4d5057cdd22c 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 edf50c1a71079dbf50162ea9af8acc9525c7b744..48683fa76ffdb3efe7fc097210bb2ea7457577c7 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 e5b984c226652da945a9cdce349bb87cbdb27b58..3aee2d69d7250fa5b7ab27edc169e984dc810f3f 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 76a4edb0601dbbd0a622f46537c6b299343cab7c..210f5ffa54cf243b29d09dad739faa033037a356 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 46045d6f00a9ab7080aac4d70237fae7a099dba0..f67e9dce76d091c8e921ce62a881407ac813d7dd 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 baaab38e7251ef4bd7487b629845f12185696708..a53bd5cd813539480af7d8d3ef8c7d6b034a262c 100644 (file)
@@ -51,6 +51,7 @@ private:
     virtual RenderWidget* renderWidgetForJSBindings() const;
 
     void setupApplet() const;
+    bool canEmbedJava() const;
 
     virtual void insertedIntoDocument();
     virtual void removedFromDocument();
index 77164a5f6c8a97ff2215727cfb5c8a18a0f54c0f..696f4e036b8566dfc5402e1bfff1827c3031f3ab 100644 (file)
@@ -222,6 +222,7 @@ role
 rows
 rowspan
 rules
+sandbox
 scheme
 scope
 scrollamount
index 84958c2cd8c916ba530892d73d512201b4be11f7..7598da2820407c96f4538519582f484e63008ff9 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 1437e2c96ba1b92464291d44e1e1723aaa88a116..308a1003fc1498de42dc9589c45cdecc5f9fea23 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 cae9b8d30f92c77633e4c5b380720cc4bdfaa8ec..a2f287e366f9508b0e16091196cfc3341c4ce4f8 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 e288b547f0ef6242f343ccd96e72c2a70eef898d..dad84169e139b810ed0ff8f8ccc1fa5985014673 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 a88a29993bc188c5531912c819da3c472a36f87b..643fc51a5b9488fcff89d02dc6de335e9db87d1a 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 f0f8b6afc8a8877957cac9baa028f43a9c920820..7a21280ac79b7989c5d95eddd99161497b447937 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 3745cd1a45fbba0c3f1c1daa31974fe3845703ed..52453c678dcb77ebc9c5eceeb215c8c2f0dd356b 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 216bc532827f0b7c050f0d41d62da399c7f43337..6c676b96fde4696fed70d72a243b6a6b60ef6daf 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 e7d51c79742dc055b7120f7ab7e86011248b6039..d71263b7c881f8b68dedfc871b58a3a34a51d400 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 58f54bdf6ee0844b9e917a211dcc4b476a0050dc..8bb70e0b3789f366b2ac8a2bfec6722b9b4e938d 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 b625fba494476a400a070acfa18209d430644844..9a413b143c5d89a2d1e95c064971fcb746b47c21 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 7c32f03d299eca2684eeffa8ff101527cebc20b8..bf3221f0846449d745480078054a5ba5e3d556ca 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 a1107460e6d22639180cdaaf12b48ef5633a10a6..2dde7705c308cceb639849405cfe6a5cace6988d 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.