Title: [231911] trunk
Revision
231911
Author
[email protected]
Date
2018-05-17 11:23:23 -0700 (Thu, 17 May 2018)

Log Message

Cross-Origin-Options: deny/allow-postmessage should prevent getting navigated by cross-origin scripts
https://bugs.webkit.org/show_bug.cgi?id=185681
<rdar://problem/40296313>

Reviewed by Geoffrey Garen.

Source/WebCore:

Update our canNavigate() implementation [1] to take into account the Cross-Origin-Options header.
If the window being navigated or the window trigerring the navigation have a Cross-Origin-Options
header value different than 'allow', then the attempt to navigate will be blocked.

Note that it was already not possible to navigate via setting window.location since trying to set
it would throw a SecurityError with 'Cross-Origin-Options: deny/allow-postmessage'. However, it was
possible to trigger a "targeted" navigation via <a target="foo"> or open(url, "foo").

[1] https://html.spec.whatwg.org/#allowed-to-navigate

Tests: http/wpt/cross-origin-options/navigation-from-opener-via-open-target.html
       http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target.html

* dom/Document.cpp:
(WebCore::Document::canNavigate):

LayoutTests:

Add layout test coverage.

* http/wpt/cross-origin-options/navigation-from-opener-via-open-target-expected.txt: Added.
* http/wpt/cross-origin-options/navigation-from-opener-via-open-target.html: Added.
* http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target-expected.txt: Added.
* http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target.html: Added.
* http/wpt/cross-origin-options/resources/destination.html: Added.
* http/wpt/cross-origin-options/resources/navigate-parent-via-anchor.html: Added.
* http/wpt/cross-origin-options/resources/navigation-from-subframe-frame.py: Added.
(main):
* http/wpt/cross-origin-options/resources/utils.js:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (231910 => 231911)


--- trunk/LayoutTests/ChangeLog	2018-05-17 18:16:56 UTC (rev 231910)
+++ trunk/LayoutTests/ChangeLog	2018-05-17 18:23:23 UTC (rev 231911)
@@ -1,3 +1,23 @@
+2018-05-17  Chris Dumez  <[email protected]>
+
+        Cross-Origin-Options: deny/allow-postmessage should prevent getting navigated by cross-origin scripts
+        https://bugs.webkit.org/show_bug.cgi?id=185681
+        <rdar://problem/40296313>
+
+        Reviewed by Geoffrey Garen.
+
+        Add layout test coverage.
+
+        * http/wpt/cross-origin-options/navigation-from-opener-via-open-target-expected.txt: Added.
+        * http/wpt/cross-origin-options/navigation-from-opener-via-open-target.html: Added.
+        * http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target-expected.txt: Added.
+        * http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target.html: Added.
+        * http/wpt/cross-origin-options/resources/destination.html: Added.
+        * http/wpt/cross-origin-options/resources/navigate-parent-via-anchor.html: Added.
+        * http/wpt/cross-origin-options/resources/navigation-from-subframe-frame.py: Added.
+        (main):
+        * http/wpt/cross-origin-options/resources/utils.js:
+
 2018-05-17  Brent Fulgham  <[email protected]>
 
         Storage Access API: Allow documents that have been granted storage access to also do a popup

Added: trunk/LayoutTests/http/wpt/cross-origin-options/navigation-from-opener-via-open-target-expected.txt (0 => 231911)


--- trunk/LayoutTests/http/wpt/cross-origin-options/navigation-from-opener-via-open-target-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/cross-origin-options/navigation-from-opener-via-open-target-expected.txt	2018-05-17 18:23:23 UTC (rev 231911)
@@ -0,0 +1,9 @@
+CONSOLE MESSAGE: line 23: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/serve-cross-origin-options-header.py?value=deny' from frame with URL 'http://localhost:8800/WebKit/cross-origin-options/navigation-from-opener-via-open-target.html'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 44: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/serve-cross-origin-options-header.py?value=allow-postmessage' from frame with URL 'http://localhost:8800/WebKit/cross-origin-options/navigation-from-opener-via-open-target.html'. Navigation was not allowed due to Cross-Origin-Options header.
+
+
+PASS 'Cross-Origin-Options: deny' prevents navigation from opener via open() target 
+PASS 'Cross-Origin-Options: allow-postmessage' prevents navigation from opener via open() target 
+PASS 'Cross-Origin-Options: allow' does not prevent navigation from opener via open() target 
+

Added: trunk/LayoutTests/http/wpt/cross-origin-options/navigation-from-opener-via-open-target.html (0 => 231911)


--- trunk/LayoutTests/http/wpt/cross-origin-options/navigation-from-opener-via-open-target.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/cross-origin-options/navigation-from-opener-via-open-target.html	2018-05-17 18:23:23 UTC (rev 231911)
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Tests that 'Cross-Origin-Options: deny / allow-postmessage' prevents a cross-origin opener from navigating us</title>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+
+promise_test(t => {
+    return withPopup("serve-cross-origin-options-header.py?value=deny", true /* isCrossOrigin */, "foo1").then((result) => {
+        return new Promise((resolve) => {
+            window._onmessage_ = (msg) => {
+                assert_not_equals(msg.source, result.window, "Existing window should not navigate");
+            }
+
+            let destinationURL = get_host_info().HTTP_ORIGIN + "/WebKit/cross-origin-options/resources/destination.html";
+            w = open(destinationURL, "foo1");
+            // If a window with the given name is found but cannot be navigated, a new one is created, as if we could
+            // not find the given window.
+            assert_not_equals(w, result.window, "open() should a new window");
+
+            t.step_timeout(() => {
+               window._onmessage_ = null;
+               resolve();
+            }, 200);
+        });
+    });
+}, "'Cross-Origin-Options: deny' prevents navigation from opener via open() target");
+
+promise_test(t => {
+    return withPopup("serve-cross-origin-options-header.py?value=allow-postmessage", true /* isCrossOrigin */, "foo2").then((result) => {
+        return new Promise((resolve) => {
+            window._onmessage_ = (msg) => {
+                assert_not_equals(msg.source, result.window, "Existing window should not navigate");
+            }
+
+            let destinationURL = get_host_info().HTTP_ORIGIN + "/WebKit/cross-origin-options/resources/destination.html";
+            w = open(destinationURL, "foo2");
+            // If a window with the given name is found but cannot be navigated, a new one is created, as if we could
+            // not find the given window.
+            assert_not_equals(w, result.window, "open() should a new window");
+
+            t.step_timeout(() => {
+               window._onmessage_ = null;
+               resolve();
+            }, 200);
+        });
+    });
+}, "'Cross-Origin-Options: allow-postmessage' prevents navigation from opener via open() target");
+
+promise_test(t => {
+    return withPopup("serve-cross-origin-options-header.py?value=allow", true /* isCrossOrigin */, "foo3").then((result) => {
+        return new Promise((resolve) => {
+            window._onmessage_ = () => {
+                window._onmessage_ = null;
+                resolve();
+            }
+
+            let destinationURL = get_host_info().HTTP_ORIGIN + "/WebKit/cross-origin-options/resources/destination.html";
+            w = open(destinationURL, "foo3");
+            assert_equals(w, result.window, "open() should return the same window");
+        });
+    });
+}, "'Cross-Origin-Options: allow' does not prevent navigation from opener via open() target");
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target-expected.txt (0 => 231911)


--- trunk/LayoutTests/http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target-expected.txt	2018-05-17 18:23:23 UTC (rev 231911)
@@ -0,0 +1,35 @@
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=deny&target=_top' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_top'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=deny&target=_top' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_top'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=allow-postmessage&target=_top' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_top'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=allow-postmessage&target=_top' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_top'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=deny&target=_parent' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_parent'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=deny&target=_parent' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_parent'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=allow-postmessage&target=_parent' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_parent'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=allow-postmessage&target=_parent' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_parent'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=deny&target=foo1' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=foo1'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=deny&target=foo1' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=foo1'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=allow-postmessage&target=foo2' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=foo2'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=allow-postmessage&target=foo2' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=foo2'. Navigation was not allowed due to Cross-Origin-Options header.
+
+
+PASS 'Cross-Origin-Options: deny' prevents navigation from cross-origin sub-frame (using <a target=_top>) 
+PASS 'Cross-Origin-Options: allow-postmessage' prevents navigation from cross-origin sub-frame (using <a target=_top>) 
+PASS 'Cross-Origin-Options: allow' does not prevent navigation from cross-origin sub-frame (using <a target=_top>) 
+PASS 'Cross-Origin-Options: deny' prevents navigation from cross-origin sub-frame (using <a target=_parent>) 
+PASS 'Cross-Origin-Options: allow-postmessage' prevents navigation from cross-origin sub-frame (using <a target=_parent>) 
+PASS 'Cross-Origin-Options: allow' does not prevent navigation from cross-origin sub-frame (using <a target=_parent>) 
+PASS 'Cross-Origin-Options: deny' prevents navigation from cross-origin sub-frame (using <a target=windowName) 
+PASS 'Cross-Origin-Options: allow-postmessage' prevents navigation from cross-origin sub-frame (using <a target=windowName) 
+PASS 'Cross-Origin-Options: allow' does not prevent navigation from cross-origin sub-frame (using <a target=windowName>) 
+

Added: trunk/LayoutTests/http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target.html (0 => 231911)


--- trunk/LayoutTests/http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target.html	2018-05-17 18:23:23 UTC (rev 231911)
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Tests that 'Cross-Origin-Options: deny / allow-postmessage' prevents a cross-origin iframe from navigating us</title>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+
+promise_test(t => {
+    return withPopup("navigation-from-subframe-frame.py?value=deny&target=_top", false /* isCrossOrigin */).then((result) => {
+        return new Promise((resolve) => {
+            window._onmessage_ = t.unreached_func("Should not have navigated");
+            t.step_timeout(() => {
+               window._onmessage_ = null;
+               resolve();
+            }, 200);
+        });
+    });
+}, "'Cross-Origin-Options: deny' prevents navigation from cross-origin sub-frame (using <a target=_top>)");
+
+promise_test(t => {
+    return withPopup("navigation-from-subframe-frame.py?value=allow-postmessage&target=_top", false /* isCrossOrigin */).then((result) => {
+        return new Promise((resolve) => {
+            window._onmessage_ = t.unreached_func("Should not have navigated");
+            t.step_timeout(() => {
+               window._onmessage_ = null;
+               resolve();
+            }, 200);
+        });
+    });
+}, "'Cross-Origin-Options: allow-postmessage' prevents navigation from cross-origin sub-frame (using <a target=_top>)");
+
+promise_test(t => {
+    return withPopup("navigation-from-subframe-frame.py?value=allow&target=_top", false /* isCrossOrigin */).then((result) => {
+        return new Promise((resolve) => {
+            window._onmessage_ = () => {
+                resolve();
+            };
+        });
+    });
+}, "'Cross-Origin-Options: allow' does not prevent navigation from cross-origin sub-frame (using <a target=_top>)");
+
+promise_test(t => {
+    return withPopup("navigation-from-subframe-frame.py?value=deny&target=_parent", false /* isCrossOrigin */).then((result) => {
+        return new Promise((resolve) => {
+            window._onmessage_ = t.unreached_func("Should not have navigated");
+            t.step_timeout(() => {
+               window._onmessage_ = null;
+               resolve();
+            }, 200);
+        });
+    });
+}, "'Cross-Origin-Options: deny' prevents navigation from cross-origin sub-frame (using <a target=_parent>)");
+
+promise_test(t => {
+    return withPopup("navigation-from-subframe-frame.py?value=allow-postmessage&target=_parent", false /* isCrossOrigin */).then((result) => {
+        return new Promise((resolve) => {
+            window._onmessage_ = t.unreached_func("Should not have navigated");
+            t.step_timeout(() => {
+               window._onmessage_ = null;
+               resolve();
+            }, 200);
+        });
+    });
+}, "'Cross-Origin-Options: allow-postmessage' prevents navigation from cross-origin sub-frame (using <a target=_parent>)");
+
+promise_test(t => {
+    return withPopup("navigation-from-subframe-frame.py?value=allow&target=_parent", false /* isCrossOrigin */).then((result) => {
+        return new Promise((resolve) => {
+            window._onmessage_ = () => {
+                resolve();
+            }; 
+        });
+    });
+}, "'Cross-Origin-Options: allow' does not prevent navigation from cross-origin sub-frame (using <a target=_parent>)");
+
+promise_test(t => {
+    return withPopup("navigation-from-subframe-frame.py?value=deny&target=foo1", false /* isCrossOrigin */, "foo1").then((result) => {
+        return new Promise((resolve) => {
+            window._onmessage_ = t.unreached_func("Should not have navigated");
+            t.step_timeout(() => {
+               window._onmessage_ = null;
+               resolve();
+            }, 200);
+        });
+    }); 
+}, "'Cross-Origin-Options: deny' prevents navigation from cross-origin sub-frame (using <a target=windowName)");
+
+promise_test(t => {
+    return withPopup("navigation-from-subframe-frame.py?value=allow-postmessage&target=foo2", false /* isCrossOrigin */, "foo2").then((result) => {
+        return new Promise((resolve) => {
+            window._onmessage_ = t.unreached_func("Should not have navigated");
+            t.step_timeout(() => {
+               window._onmessage_ = null;
+               resolve();
+            }, 200);
+        });
+    });
+}, "'Cross-Origin-Options: allow-postmessage' prevents navigation from cross-origin sub-frame (using <a target=windowName)");
+
+promise_test(t => {
+    return withPopup("navigation-from-subframe-frame.py?value=allow&target=foo3", false /* isCrossOrigin */, "foo3").then((result) => {
+        return new Promise((resolve) => {
+            window._onmessage_ = () => {
+                resolve();
+            };
+        });
+    });
+}, "'Cross-Origin-Options: allow' does not prevent navigation from cross-origin sub-frame (using <a target=windowName>)");
+
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/http/wpt/cross-origin-options/resources/destination.html (0 => 231911)


--- trunk/LayoutTests/http/wpt/cross-origin-options/resources/destination.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/cross-origin-options/resources/destination.html	2018-05-17 18:23:23 UTC (rev 231911)
@@ -0,0 +1,7 @@
+<body>
+DESTINATION
+<script>
+if (window.opener)
+    window.opener.postMessage("navigated", "*");
+</script>
+</body>

Added: trunk/LayoutTests/http/wpt/cross-origin-options/resources/navigate-parent-via-anchor.html (0 => 231911)


--- trunk/LayoutTests/http/wpt/cross-origin-options/resources/navigate-parent-via-anchor.html	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/cross-origin-options/resources/navigate-parent-via-anchor.html	2018-05-17 18:23:23 UTC (rev 231911)
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<a id="testAnchor">Click me</a>
+<script>
+const RESOURCES_DIR = "/WebKit/cross-origin-options/resources/";
+_onload_ = () => {
+    let params = new URLSearchParams(location.search);
+    testAnchor.target= params.get('target')
+    testAnchor.href = "" + RESOURCES_DIR + "destination.html";
+    testAnchor.click();
+}
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/http/wpt/cross-origin-options/resources/navigation-from-subframe-frame.py (0 => 231911)


--- trunk/LayoutTests/http/wpt/cross-origin-options/resources/navigation-from-subframe-frame.py	                        (rev 0)
+++ trunk/LayoutTests/http/wpt/cross-origin-options/resources/navigation-from-subframe-frame.py	2018-05-17 18:23:23 UTC (rev 231911)
@@ -0,0 +1,17 @@
+def main(request, response):
+    headers = [("Content-Type", "text/html"),
+               ("Cross-Origin-Options", request.GET['value']),]
+    return 200, headers, """<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+const RESOURCES_DIR = "/WebKit/cross-origin-options/resources/";
+let f = document.createElement("iframe");
+f.src = "" + RESOURCES_DIR + "navigate-parent-via-anchor.html?target=%s";
+document.body.prepend(f);
+</script>
+</body>
+</html>""" % request.GET['target']

Modified: trunk/LayoutTests/http/wpt/cross-origin-options/resources/utils.js (231910 => 231911)


--- trunk/LayoutTests/http/wpt/cross-origin-options/resources/utils.js	2018-05-17 18:16:56 UTC (rev 231910)
+++ trunk/LayoutTests/http/wpt/cross-origin-options/resources/utils.js	2018-05-17 18:23:23 UTC (rev 231911)
@@ -54,7 +54,7 @@
     });
 }
 
-async function withPopup(resourceFile, crossOrigin)
+async function withPopup(resourceFile, crossOrigin, windowName)
 {
     return new Promise((resolve) => { 
         let resourceURL = crossOrigin ? get_host_info().HTTP_REMOTE_ORIGIN : get_host_info().HTTP_ORIGIN;
@@ -61,7 +61,7 @@
         resourceURL += RESOURCES_DIR;
         resourceURL += resourceFile;
 
-        let w = open(resourceURL);
+        let w = open(resourceURL, windowName);
         if (crossOrigin) {
             waitForCrossOriginLoad(w).then(() => {
                 resolve({ 'window': w });

Added: trunk/LayoutTests/platform/wk2/http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target-expected.txt (0 => 231911)


--- trunk/LayoutTests/platform/wk2/http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/wk2/http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target-expected.txt	2018-05-17 18:23:23 UTC (rev 231911)
@@ -0,0 +1,35 @@
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=deny&target=_top' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_top'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=deny&target=_top' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_top'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=allow-postmessage&target=_top' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_top'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=allow-postmessage&target=_top' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_top'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=deny&target=_parent' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_parent'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=deny&target=_parent' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_parent'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=allow-postmessage&target=_parent' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_parent'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=allow-postmessage&target=_parent' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=_parent'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=deny&target=foo1' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=foo1'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=deny&target=foo1' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=foo1'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: line 14: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=allow-postmessage&target=foo2' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=foo2'. Navigation was not allowed due to Cross-Origin-Options header.
+
+CONSOLE MESSAGE: Unsafe _javascript_ attempt to initiate navigation for frame with URL 'http://localhost:8800/WebKit/cross-origin-options/resources/navigation-from-subframe-frame.py?value=allow-postmessage&target=foo2' from frame with URL 'http://127.0.0.1:8800/WebKit/cross-origin-options/resources/navigate-parent-via-anchor.html?target=foo2'. Navigation was not allowed due to Cross-Origin-Options header.
+
+
+PASS 'Cross-Origin-Options: deny' prevents navigation from cross-origin sub-frame (using <a target=_top>) 
+PASS 'Cross-Origin-Options: allow-postmessage' prevents navigation from cross-origin sub-frame (using <a target=_top>) 
+PASS 'Cross-Origin-Options: allow' does not prevent navigation from cross-origin sub-frame (using <a target=_top>) 
+PASS 'Cross-Origin-Options: deny' prevents navigation from cross-origin sub-frame (using <a target=_parent>) 
+PASS 'Cross-Origin-Options: allow-postmessage' prevents navigation from cross-origin sub-frame (using <a target=_parent>) 
+PASS 'Cross-Origin-Options: allow' does not prevent navigation from cross-origin sub-frame (using <a target=_parent>) 
+PASS 'Cross-Origin-Options: deny' prevents navigation from cross-origin sub-frame (using <a target=windowName) 
+PASS 'Cross-Origin-Options: allow-postmessage' prevents navigation from cross-origin sub-frame (using <a target=windowName) 
+PASS 'Cross-Origin-Options: allow' does not prevent navigation from cross-origin sub-frame (using <a target=windowName>) 
+

Modified: trunk/Source/WebCore/ChangeLog (231910 => 231911)


--- trunk/Source/WebCore/ChangeLog	2018-05-17 18:16:56 UTC (rev 231910)
+++ trunk/Source/WebCore/ChangeLog	2018-05-17 18:23:23 UTC (rev 231911)
@@ -1,3 +1,27 @@
+2018-05-17  Chris Dumez  <[email protected]>
+
+        Cross-Origin-Options: deny/allow-postmessage should prevent getting navigated by cross-origin scripts
+        https://bugs.webkit.org/show_bug.cgi?id=185681
+        <rdar://problem/40296313>
+
+        Reviewed by Geoffrey Garen.
+
+        Update our canNavigate() implementation [1] to take into account the Cross-Origin-Options header.
+        If the window being navigated or the window trigerring the navigation have a Cross-Origin-Options
+        header value different than 'allow', then the attempt to navigate will be blocked.
+
+        Note that it was already not possible to navigate via setting window.location since trying to set
+        it would throw a SecurityError with 'Cross-Origin-Options: deny/allow-postmessage'. However, it was
+        possible to trigger a "targeted" navigation via <a target="foo"> or open(url, "foo").
+
+        [1] https://html.spec.whatwg.org/#allowed-to-navigate
+
+        Tests: http/wpt/cross-origin-options/navigation-from-opener-via-open-target.html
+               http/wpt/cross-origin-options/navigation-from-subframe-via-anchor-target.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::canNavigate):
+
 2018-05-17  Brent Fulgham  <[email protected]>
 
         Storage Access API: Allow documents that have been granted storage access to also do a popup

Modified: trunk/Source/WebCore/dom/Document.cpp (231910 => 231911)


--- trunk/Source/WebCore/dom/Document.cpp	2018-05-17 18:16:56 UTC (rev 231910)
+++ trunk/Source/WebCore/dom/Document.cpp	2018-05-17 18:23:23 UTC (rev 231911)
@@ -3173,6 +3173,17 @@
     if (!targetFrame)
         return true;
 
+    if (m_frame != targetFrame) {
+        auto sourceCrossOriginOptions = m_frame->window() ? m_frame->window()->crossOriginOptions() : CrossOriginOptions::Allow;
+        auto destinationCrossOriginOptions = targetFrame->window() ? targetFrame->window()->crossOriginOptions() : CrossOriginOptions::Allow;
+        if (sourceCrossOriginOptions != CrossOriginOptions::Allow || destinationCrossOriginOptions != CrossOriginOptions::Allow) {
+            if (m_frame->document() && targetFrame->document() && !m_frame->document()->securityOrigin().canAccess(targetFrame->document()->securityOrigin())) {
+                printNavigationErrorMessage(targetFrame, url(), ASCIILiteral("Navigation was not allowed due to Cross-Origin-Options header."));
+                return false;
+            }
+        }
+    }
+
     // Cases (i), (ii) and (iii) pass the tests from the specifications but might not pass the "security origin" tests.
 
     // i. A frame can navigate its top ancestor when its 'allow-top-navigation' flag is set (sometimes known as 'frame-busting').
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to