From 7b91738ddc761fee01c2c20cf7f65b3693e7a156 Mon Sep 17 00:00:00 2001 From: Chris Dumez Date: Mon, 15 Oct 2018 15:34:39 +0000 Subject: [PATCH] Restrict browsing context lookup by name to frames that are related to one another https://bugs.webkit.org/show_bug.cgi?id=190475 Reviewed by Alex Christensen. Source/WebCore: Update our frame lookup by name logic to take in the active / requesting frame and only a return a frame that is related to it. By related to it, I mean: - Ancestor <-> Descendant relationship - Opener <-> Openee relationship Being able to look up unrelated frames makes process swapping difficult so we need to be stricter. This change is being discussed at: - https://github.com/whatwg/html/issues/313 Tests: http/tests/dom/new-window-can-target-opener.html http/tests/dom/noopener-window-cannot-target-opener.html http/tests/dom/noopener-window-not-targetable.html http/tests/dom/noopener-window-not-targetable2.html http/tests/dom/noreferrer-window-not-targetable.html http/tests/dom/opened-window-not-targetable-after-disowning-opener.html * loader/FrameLoader.cpp: (WebCore::FrameLoader::findFrameForNavigation): * page/FrameTree.cpp: (WebCore::isFrameFamiliarWith): (WebCore::FrameTree::find const): * page/FrameTree.h: * rendering/HitTestResult.cpp: (WebCore::HitTestResult::targetFrame const): Source/WebKit: * WebProcess/Plugins/PluginView.cpp: (WebKit::PluginView::performJavaScriptURLRequest): Source/WebKitLegacy/mac: * WebView/WebFrame.mm: (-[WebFrame findFrameNamed:]): LayoutTests: * http/tests/dom/new-window-can-target-opener-expected.txt: Added. * http/tests/dom/new-window-can-target-opener.html: Added. * http/tests/dom/noopener-window-cannot-target-opener-expected.txt: Added. * http/tests/dom/noopener-window-cannot-target-opener.html: Added. * http/tests/dom/noopener-window-not-targetable-expected.txt: Added. * http/tests/dom/noopener-window-not-targetable.html: Added. * http/tests/dom/noopener-window-not-targetable2-expected.txt: Added. * http/tests/dom/noopener-window-not-targetable2.html: Added. * http/tests/dom/noreferrer-window-not-targetable-expected.txt: Added. * http/tests/dom/noreferrer-window-not-targetable.html: Added. * http/tests/dom/opened-window-not-targetable-after-disowning-opener-expected.txt: Added. * http/tests/dom/opened-window-not-targetable-after-disowning-opener.html: Added. * http/tests/dom/resources/new-window-can-target-opener-win.html: Added. * http/tests/dom/resources/noopener-window-cannot-target-opener-win.html: Added. Add layout test coverage. * fast/dom/Window/a-rel-noopener-expected.txt: * fast/dom/Window/area-rel-noopener-expected.txt: * fast/dom/Window/resources/rel-noopener.js: * http/tests/navigation/no-referrer-target-blank-expected.txt: * http/tests/navigation/resources/no-referrer-helper.php: * platform/mac-wk1/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt: * platform/wk2/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt: Update / rebaseline existing tests to reflect behavior change. Canonical link: https://commits.webkit.org/205486@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237112 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- LayoutTests/ChangeLog | 32 +++++++++++++++++ .../dom/Window/a-rel-noopener-expected.txt | 3 +- .../dom/Window/area-rel-noopener-expected.txt | 3 +- .../fast/dom/Window/resources/rel-noopener.js | 5 ++- .../new-window-can-target-opener-expected.txt | 9 +++++ .../dom/new-window-can-target-opener.html | 20 +++++++++++ ...r-window-cannot-target-opener-expected.txt | 9 +++++ .../noopener-window-cannot-target-opener.html | 21 +++++++++++ ...oopener-window-not-targetable-expected.txt | 11 ++++++ .../dom/noopener-window-not-targetable.html | 30 ++++++++++++++++ ...opener-window-not-targetable2-expected.txt | 12 +++++++ .../dom/noopener-window-not-targetable2.html | 30 ++++++++++++++++ ...eferrer-window-not-targetable-expected.txt | 11 ++++++ .../dom/noreferrer-window-not-targetable.html | 29 +++++++++++++++ ...etable-after-disowning-opener-expected.txt | 11 ++++++ ...not-targetable-after-disowning-opener.html | 30 ++++++++++++++++ .../new-window-can-target-opener-win.html | 35 +++++++++++++++++++ ...pener-window-cannot-target-opener-win.html | 29 +++++++++++++++ .../navigation/no-referrer-reset-expected.txt | 4 +-- .../no-referrer-subframe-expected.txt | 5 +-- .../no-referrer-target-blank-expected.txt | 5 +-- .../resources/no-referrer-helper.php | 7 ++-- .../noreferrer-window-name-expected.txt | 6 ---- .../noreferrer-window-name-expected.txt | 2 -- Source/WebCore/ChangeLog | 34 ++++++++++++++++++ Source/WebCore/loader/FrameLoader.cpp | 4 +-- Source/WebCore/page/FrameTree.cpp | 22 ++++++++++-- Source/WebCore/page/FrameTree.h | 2 +- Source/WebCore/rendering/HitTestResult.cpp | 6 ++-- Source/WebKit/ChangeLog | 10 ++++++ .../WebKit/WebProcess/Plugins/PluginView.cpp | 2 +- Source/WebKitLegacy/mac/ChangeLog | 10 ++++++ Source/WebKitLegacy/mac/WebView/WebFrame.mm | 2 +- Source/WebKitLegacy/win/WebFrame.cpp | 2 +- 34 files changed, 417 insertions(+), 36 deletions(-) create mode 100644 LayoutTests/http/tests/dom/new-window-can-target-opener-expected.txt create mode 100644 LayoutTests/http/tests/dom/new-window-can-target-opener.html create mode 100644 LayoutTests/http/tests/dom/noopener-window-cannot-target-opener-expected.txt create mode 100644 LayoutTests/http/tests/dom/noopener-window-cannot-target-opener.html create mode 100644 LayoutTests/http/tests/dom/noopener-window-not-targetable-expected.txt create mode 100644 LayoutTests/http/tests/dom/noopener-window-not-targetable.html create mode 100644 LayoutTests/http/tests/dom/noopener-window-not-targetable2-expected.txt create mode 100644 LayoutTests/http/tests/dom/noopener-window-not-targetable2.html create mode 100644 LayoutTests/http/tests/dom/noreferrer-window-not-targetable-expected.txt create mode 100644 LayoutTests/http/tests/dom/noreferrer-window-not-targetable.html create mode 100644 LayoutTests/http/tests/dom/opened-window-not-targetable-after-disowning-opener-expected.txt create mode 100644 LayoutTests/http/tests/dom/opened-window-not-targetable-after-disowning-opener.html create mode 100644 LayoutTests/http/tests/dom/resources/new-window-can-target-opener-win.html create mode 100644 LayoutTests/http/tests/dom/resources/noopener-window-cannot-target-opener-win.html diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index ed9c55d65d79..573bf15771b0 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,35 @@ +2018-10-15 Chris Dumez + + Restrict browsing context lookup by name to frames that are related to one another + https://bugs.webkit.org/show_bug.cgi?id=190475 + + Reviewed by Alex Christensen. + + * http/tests/dom/new-window-can-target-opener-expected.txt: Added. + * http/tests/dom/new-window-can-target-opener.html: Added. + * http/tests/dom/noopener-window-cannot-target-opener-expected.txt: Added. + * http/tests/dom/noopener-window-cannot-target-opener.html: Added. + * http/tests/dom/noopener-window-not-targetable-expected.txt: Added. + * http/tests/dom/noopener-window-not-targetable.html: Added. + * http/tests/dom/noopener-window-not-targetable2-expected.txt: Added. + * http/tests/dom/noopener-window-not-targetable2.html: Added. + * http/tests/dom/noreferrer-window-not-targetable-expected.txt: Added. + * http/tests/dom/noreferrer-window-not-targetable.html: Added. + * http/tests/dom/opened-window-not-targetable-after-disowning-opener-expected.txt: Added. + * http/tests/dom/opened-window-not-targetable-after-disowning-opener.html: Added. + * http/tests/dom/resources/new-window-can-target-opener-win.html: Added. + * http/tests/dom/resources/noopener-window-cannot-target-opener-win.html: Added. + Add layout test coverage. + + * fast/dom/Window/a-rel-noopener-expected.txt: + * fast/dom/Window/area-rel-noopener-expected.txt: + * fast/dom/Window/resources/rel-noopener.js: + * http/tests/navigation/no-referrer-target-blank-expected.txt: + * http/tests/navigation/resources/no-referrer-helper.php: + * platform/mac-wk1/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt: + * platform/wk2/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt: + Update / rebaseline existing tests to reflect behavior change. + 2018-10-15 YUHAN WU Implement error handler of MediaRecorder diff --git a/LayoutTests/fast/dom/Window/a-rel-noopener-expected.txt b/LayoutTests/fast/dom/Window/a-rel-noopener-expected.txt index 8e8704ae8b34..e135f52a4d55 100644 --- a/LayoutTests/fast/dom/Window/a-rel-noopener-expected.txt +++ b/LayoutTests/fast/dom/Window/a-rel-noopener-expected.txt @@ -1,3 +1,4 @@ +CONSOLE MESSAGE: line 11: PASS: window.opener is null Test that window.opener is null when a new window is opened from an anchor element with rel='noopener'. -PASS: window.opener is null + diff --git a/LayoutTests/fast/dom/Window/area-rel-noopener-expected.txt b/LayoutTests/fast/dom/Window/area-rel-noopener-expected.txt index b6ece8b59a56..e6202cd46aad 100644 --- a/LayoutTests/fast/dom/Window/area-rel-noopener-expected.txt +++ b/LayoutTests/fast/dom/Window/area-rel-noopener-expected.txt @@ -1,4 +1,5 @@ +CONSOLE MESSAGE: line 11: PASS: window.opener is null Test that window.opener is null when a new window is opened from an area element with rel='noopener'. -PASS: window.opener is null + diff --git a/LayoutTests/fast/dom/Window/resources/rel-noopener.js b/LayoutTests/fast/dom/Window/resources/rel-noopener.js index bb5d46eae397..b3b59ba30cd4 100644 --- a/LayoutTests/fast/dom/Window/resources/rel-noopener.js +++ b/LayoutTests/fast/dom/Window/resources/rel-noopener.js @@ -5,11 +5,10 @@ if (window.testRunner) { } if (document.location.hash === "#new-window") { - var console = window.open("", "originalWindow").document.getElementById("console"); if (window.opener) - console.innerText = "FAIL: window.opener is non-null"; + console.log("FAIL: window.opener is non-null"); else - console.innerText = "PASS: window.opener is null"; + console.log("PASS: window.opener is null"); testRunner.notifyDone(); } else { window.name = "originalWindow"; diff --git a/LayoutTests/http/tests/dom/new-window-can-target-opener-expected.txt b/LayoutTests/http/tests/dom/new-window-can-target-opener-expected.txt new file mode 100644 index 000000000000..72a8dce01a8e --- /dev/null +++ b/LayoutTests/http/tests/dom/new-window-can-target-opener-expected.txt @@ -0,0 +1,9 @@ +CONSOLE MESSAGE: line 15: PASS: New window should have an opener +CONSOLE MESSAGE: line 21: PASS: New window should be able to look up opener by name +CONSOLE MESSAGE: line 27: PASS: New window should have URL 'http://127.0.0.1:8000/dom/new-window-can-target-opener.html' +Make sure that windows opened via window.open can target their opener + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + + diff --git a/LayoutTests/http/tests/dom/new-window-can-target-opener.html b/LayoutTests/http/tests/dom/new-window-can-target-opener.html new file mode 100644 index 000000000000..39f13986a6ca --- /dev/null +++ b/LayoutTests/http/tests/dom/new-window-can-target-opener.html @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/LayoutTests/http/tests/dom/noopener-window-cannot-target-opener-expected.txt b/LayoutTests/http/tests/dom/noopener-window-cannot-target-opener-expected.txt new file mode 100644 index 000000000000..a23c4000140f --- /dev/null +++ b/LayoutTests/http/tests/dom/noopener-window-cannot-target-opener-expected.txt @@ -0,0 +1,9 @@ +CONSOLE MESSAGE: line 17: PASS: New window should not have an opener +CONSOLE MESSAGE: line 21: PASS: New window should have URL 'about:blank' +Make sure that windows opened with 'noopener' via window.open cannot target their opener. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS w is null + diff --git a/LayoutTests/http/tests/dom/noopener-window-cannot-target-opener.html b/LayoutTests/http/tests/dom/noopener-window-cannot-target-opener.html new file mode 100644 index 000000000000..7d0de75f0559 --- /dev/null +++ b/LayoutTests/http/tests/dom/noopener-window-cannot-target-opener.html @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/LayoutTests/http/tests/dom/noopener-window-not-targetable-expected.txt b/LayoutTests/http/tests/dom/noopener-window-not-targetable-expected.txt new file mode 100644 index 000000000000..63d7b07d0cab --- /dev/null +++ b/LayoutTests/http/tests/dom/noopener-window-not-targetable-expected.txt @@ -0,0 +1,11 @@ +Make sure that windows opened with 'noopener' via an anchor are not targetable. If testing manually, you should see 2 tabs open. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS w.location.href is "about:blank" +PASS testRunner.windowCount() is 3 +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/http/tests/dom/noopener-window-not-targetable.html b/LayoutTests/http/tests/dom/noopener-window-not-targetable.html new file mode 100644 index 000000000000..34f9c53b0bd8 --- /dev/null +++ b/LayoutTests/http/tests/dom/noopener-window-not-targetable.html @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/LayoutTests/http/tests/dom/noopener-window-not-targetable2-expected.txt b/LayoutTests/http/tests/dom/noopener-window-not-targetable2-expected.txt new file mode 100644 index 000000000000..9cd97618f018 --- /dev/null +++ b/LayoutTests/http/tests/dom/noopener-window-not-targetable2-expected.txt @@ -0,0 +1,12 @@ +Make sure that windows opened with 'noopener' via window.open are not targetable. If testing manually, you should see 2 tabs open. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS w is null +PASS w.location.href is "about:blank" +PASS testRunner.windowCount() is 3 +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/http/tests/dom/noopener-window-not-targetable2.html b/LayoutTests/http/tests/dom/noopener-window-not-targetable2.html new file mode 100644 index 000000000000..d9c019bb2438 --- /dev/null +++ b/LayoutTests/http/tests/dom/noopener-window-not-targetable2.html @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/LayoutTests/http/tests/dom/noreferrer-window-not-targetable-expected.txt b/LayoutTests/http/tests/dom/noreferrer-window-not-targetable-expected.txt new file mode 100644 index 000000000000..9ebeb73aeb2f --- /dev/null +++ b/LayoutTests/http/tests/dom/noreferrer-window-not-targetable-expected.txt @@ -0,0 +1,11 @@ +Make sure that windows opened with 'noreferrer' are not targetable. If testing manually, you should see 2 tabs open. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS w.location.href is "about:blank" +PASS testRunner.windowCount() is 3 +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/http/tests/dom/noreferrer-window-not-targetable.html b/LayoutTests/http/tests/dom/noreferrer-window-not-targetable.html new file mode 100644 index 000000000000..842921c4d038 --- /dev/null +++ b/LayoutTests/http/tests/dom/noreferrer-window-not-targetable.html @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/LayoutTests/http/tests/dom/opened-window-not-targetable-after-disowning-opener-expected.txt b/LayoutTests/http/tests/dom/opened-window-not-targetable-after-disowning-opener-expected.txt new file mode 100644 index 000000000000..46f5dc4a4d09 --- /dev/null +++ b/LayoutTests/http/tests/dom/opened-window-not-targetable-after-disowning-opener-expected.txt @@ -0,0 +1,11 @@ +Make sure that windows opened via window.open are not targetable by their opener after it is disowned. If testing manually, you should see 2 tabs open. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS w.location.href is "about:blank" +PASS testRunner.windowCount() is 3 +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/http/tests/dom/opened-window-not-targetable-after-disowning-opener.html b/LayoutTests/http/tests/dom/opened-window-not-targetable-after-disowning-opener.html new file mode 100644 index 000000000000..84ff71bab37f --- /dev/null +++ b/LayoutTests/http/tests/dom/opened-window-not-targetable-after-disowning-opener.html @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/LayoutTests/http/tests/dom/resources/new-window-can-target-opener-win.html b/LayoutTests/http/tests/dom/resources/new-window-can-target-opener-win.html new file mode 100644 index 000000000000..8613a48b7320 --- /dev/null +++ b/LayoutTests/http/tests/dom/resources/new-window-can-target-opener-win.html @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/LayoutTests/http/tests/dom/resources/noopener-window-cannot-target-opener-win.html b/LayoutTests/http/tests/dom/resources/noopener-window-cannot-target-opener-win.html new file mode 100644 index 000000000000..cb880ee6d133 --- /dev/null +++ b/LayoutTests/http/tests/dom/resources/noopener-window-cannot-target-opener-win.html @@ -0,0 +1,29 @@ + + + + + + + + + diff --git a/LayoutTests/http/tests/navigation/no-referrer-reset-expected.txt b/LayoutTests/http/tests/navigation/no-referrer-reset-expected.txt index ada1d16f0d67..0eb21f7709e2 100644 --- a/LayoutTests/http/tests/navigation/no-referrer-reset-expected.txt +++ b/LayoutTests/http/tests/navigation/no-referrer-reset-expected.txt @@ -1,3 +1,5 @@ +CONSOLE MESSAGE: line 15: Referrer: http://127.0.0.1:8000/navigation/resources/no-referrer-reset-helper.php +CONSOLE MESSAGE: line 16: window.opener: http://127.0.0.1:8000/navigation/no-referrer-reset.html This tests whether referrer information gets properly set and reset when "noreferrer" links are present. We do the following: 1. Open a link in a new window: referrer is sent and window.opener is sent. 2. Click a rel="noreferrer" link: referrer is null, but window.opener remains set since the link was not opened with target="_blank". @@ -7,5 +9,3 @@ Referrer: http://127.0.0.1:8000/navigation/no-referrer-reset.html window.opener: http://127.0.0.1:8000/navigation/no-referrer-reset.html Referrer: window.opener: http://127.0.0.1:8000/navigation/no-referrer-reset.html -Referrer: http://127.0.0.1:8000/navigation/resources/no-referrer-reset-helper.php -window.opener: http://127.0.0.1:8000/navigation/no-referrer-reset.html diff --git a/LayoutTests/http/tests/navigation/no-referrer-subframe-expected.txt b/LayoutTests/http/tests/navigation/no-referrer-subframe-expected.txt index 8f6b7909992a..6b109ebff023 100644 --- a/LayoutTests/http/tests/navigation/no-referrer-subframe-expected.txt +++ b/LayoutTests/http/tests/navigation/no-referrer-subframe-expected.txt @@ -1,4 +1,5 @@ +CONSOLE MESSAGE: line 15: Referrer: +CONSOLE MESSAGE: line 16: window.opener: This tests behavior of "noreferrer" links in subframes. A referrer should not be sent and window.opener should remain null. Load subframe -Referrer: -window.opener: + diff --git a/LayoutTests/http/tests/navigation/no-referrer-target-blank-expected.txt b/LayoutTests/http/tests/navigation/no-referrer-target-blank-expected.txt index 5c32e5e71603..caadabe8e388 100644 --- a/LayoutTests/http/tests/navigation/no-referrer-target-blank-expected.txt +++ b/LayoutTests/http/tests/navigation/no-referrer-target-blank-expected.txt @@ -1,4 +1,5 @@ +CONSOLE MESSAGE: line 15: Referrer: +CONSOLE MESSAGE: line 16: window.opener: This tests the functionality of the "noreferrer" link relation on anchor tags. The link below should not send an http referrer, and the resulting window should have its opener attribute set to null. The values of the referrer and window.opener should be empty below. Start no referrer test -Referrer: -window.opener: + diff --git a/LayoutTests/http/tests/navigation/resources/no-referrer-helper.php b/LayoutTests/http/tests/navigation/resources/no-referrer-helper.php index fea93dc80907..5c2abf37aa30 100644 --- a/LayoutTests/http/tests/navigation/resources/no-referrer-helper.php +++ b/LayoutTests/http/tests/navigation/resources/no-referrer-helper.php @@ -18,11 +18,8 @@ function log(msg) document.getElementById('console').appendChild(line); } - var consoleWindow = window.open("", "consoleWindow"); - if (consoleWindow) { - consoleWindow.log(document.getElementById("referrer").innerText); - consoleWindow.log("window.opener: " + (window.opener ? window.opener.location : "")); - } + console.log(document.getElementById("referrer").innerText); + console.log("window.opener: " + (window.opener ? window.opener.location : "")); if (window.testRunner) testRunner.notifyDone(); diff --git a/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt b/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt index 0b775619c3e2..11ede65be80d 100644 --- a/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt +++ b/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt @@ -1,9 +1,3 @@ -CONSOLE MESSAGE: line 37: Unsafe JavaScript attempt to initiate navigation for frame with URL '' from frame with URL 'http://localhost:8800/html/browsers/windows/noreferrer-window-name.html'. The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener. - -CONSOLE MESSAGE: line 38: Unsafe JavaScript attempt to initiate navigation for frame with URL '' from frame with URL 'http://localhost:8800/html/browsers/windows/noreferrer-window-name.html'. The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener. - -CONSOLE MESSAGE: line 38: Unsafe JavaScript attempt to initiate navigation for frame with URL '' from frame with URL 'http://localhost:8800/html/browsers/windows/noreferrer-window-name.html'. The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener. - Harness Error (TIMEOUT), message = null diff --git a/LayoutTests/platform/wk2/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt b/LayoutTests/platform/wk2/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt index 067ed0ad6031..cba574fb9704 100644 --- a/LayoutTests/platform/wk2/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt +++ b/LayoutTests/platform/wk2/imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name-expected.txt @@ -1,5 +1,3 @@ -CONSOLE MESSAGE: Unsafe JavaScript attempt to initiate navigation for frame with URL '' from frame with URL 'http://localhost:8800/html/browsers/windows/noreferrer-window-name.html'. The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener. - Harness Error (TIMEOUT), message = null diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 2945605369e5..10d047a06b0a 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,37 @@ +2018-10-15 Chris Dumez + + Restrict browsing context lookup by name to frames that are related to one another + https://bugs.webkit.org/show_bug.cgi?id=190475 + + Reviewed by Alex Christensen. + + Update our frame lookup by name logic to take in the active / requesting frame and + only a return a frame that is related to it. By related to it, I mean: + - Ancestor <-> Descendant relationship + - Opener <-> Openee relationship + + Being able to look up unrelated frames makes process swapping difficult so we need + to be stricter. + + This change is being discussed at: + - https://github.com/whatwg/html/issues/313 + + Tests: http/tests/dom/new-window-can-target-opener.html + http/tests/dom/noopener-window-cannot-target-opener.html + http/tests/dom/noopener-window-not-targetable.html + http/tests/dom/noopener-window-not-targetable2.html + http/tests/dom/noreferrer-window-not-targetable.html + http/tests/dom/opened-window-not-targetable-after-disowning-opener.html + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::findFrameForNavigation): + * page/FrameTree.cpp: + (WebCore::isFrameFamiliarWith): + (WebCore::FrameTree::find const): + * page/FrameTree.h: + * rendering/HitTestResult.cpp: + (WebCore::HitTestResult::targetFrame const): + 2018-10-15 Alex Christensen Shrink more enum classes diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp index 8403876a361f..0beb28f664ec 100644 --- a/Source/WebCore/loader/FrameLoader.cpp +++ b/Source/WebCore/loader/FrameLoader.cpp @@ -3540,12 +3540,12 @@ bool FrameLoader::shouldTreatURLAsSrcdocDocument(const URL& url) const Frame* FrameLoader::findFrameForNavigation(const AtomicString& name, Document* activeDocument) { - Frame* frame = m_frame.tree().find(name); - // FIXME: Eventually all callers should supply the actual activeDocument so we can call canNavigate with the right document. if (!activeDocument) activeDocument = m_frame.document(); + auto* frame = m_frame.tree().find(name, activeDocument->frame() ? *activeDocument->frame() : m_frame); + if (!activeDocument->canNavigate(frame)) return nullptr; diff --git a/Source/WebCore/page/FrameTree.cpp b/Source/WebCore/page/FrameTree.cpp index 42cb333a0c09..a9fec153c978 100644 --- a/Source/WebCore/page/FrameTree.cpp +++ b/Source/WebCore/page/FrameTree.cpp @@ -208,7 +208,23 @@ Frame* FrameTree::child(const AtomicString& name) const return nullptr; } -Frame* FrameTree::find(const AtomicString& name) const +// FrameTree::find() only returns frames in pages that are related to the active +// page by an opener <-> openee relationship. +static bool isFrameFamiliarWith(Frame& frameA, Frame& frameB) +{ + if (frameA.page() == frameB.page()) + return true; + + if (auto* frameAOpener = frameA.mainFrame().loader().opener()) + return isFrameFamiliarWith(*frameAOpener, frameB); + + if (auto* frameBOpener = frameB.mainFrame().loader().opener()) + return isFrameFamiliarWith(frameA, *frameBOpener); + + return false; +} + +Frame* FrameTree::find(const AtomicString& name, Frame& activeFrame) const { // FIXME: _current is not part of the HTML specification. if (equalIgnoringASCIICase(name, "_self") || name == "_current" || name.isEmpty()) @@ -245,8 +261,8 @@ Frame* FrameTree::find(const AtomicString& name) const for (auto* otherPage : page->group().pages()) { if (otherPage == page) continue; - for (Frame* frame = &otherPage->mainFrame(); frame; frame = frame->tree().traverseNext()) { - if (frame->tree().uniqueName() == name) + for (auto* frame = &otherPage->mainFrame(); frame; frame = frame->tree().traverseNext()) { + if (frame->tree().uniqueName() == name && isFrameFamiliarWith(activeFrame, *frame)) return frame; } } diff --git a/Source/WebCore/page/FrameTree.h b/Source/WebCore/page/FrameTree.h index 0b6a763528bf..97c8f2b7a46e 100644 --- a/Source/WebCore/page/FrameTree.h +++ b/Source/WebCore/page/FrameTree.h @@ -75,7 +75,7 @@ class FrameTree { Frame* child(unsigned index) const; Frame* child(const AtomicString& name) const; - WEBCORE_EXPORT Frame* find(const AtomicString& name) const; + WEBCORE_EXPORT Frame* find(const AtomicString& name, Frame& activeFrame) const; WEBCORE_EXPORT unsigned childCount() const; WEBCORE_EXPORT Frame& top() const; diff --git a/Source/WebCore/rendering/HitTestResult.cpp b/Source/WebCore/rendering/HitTestResult.cpp index 748eae3a33d8..85eb798cd09f 100644 --- a/Source/WebCore/rendering/HitTestResult.cpp +++ b/Source/WebCore/rendering/HitTestResult.cpp @@ -177,13 +177,13 @@ Frame* HitTestResult::innerNodeFrame() const Frame* HitTestResult::targetFrame() const { if (!m_innerURLElement) - return 0; + return nullptr; Frame* frame = m_innerURLElement->document().frame(); if (!frame) - return 0; + return nullptr; - return frame->tree().find(m_innerURLElement->target()); + return frame->tree().find(m_innerURLElement->target(), *frame); } bool HitTestResult::isSelected() const diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog index 2b4f04dd8364..40db0080c112 100644 --- a/Source/WebKit/ChangeLog +++ b/Source/WebKit/ChangeLog @@ -1,3 +1,13 @@ +2018-10-15 Chris Dumez + + Restrict browsing context lookup by name to frames that are related to one another + https://bugs.webkit.org/show_bug.cgi?id=190475 + + Reviewed by Alex Christensen. + + * WebProcess/Plugins/PluginView.cpp: + (WebKit::PluginView::performJavaScriptURLRequest): + 2018-10-15 Alex Christensen Fix assertion after r237102 diff --git a/Source/WebKit/WebProcess/Plugins/PluginView.cpp b/Source/WebKit/WebProcess/Plugins/PluginView.cpp index f0752bd982a1..75808b1b45b0 100644 --- a/Source/WebKit/WebProcess/Plugins/PluginView.cpp +++ b/Source/WebKit/WebProcess/Plugins/PluginView.cpp @@ -1238,7 +1238,7 @@ void PluginView::performJavaScriptURLRequest(URLRequest* request) if (!request->target().isNull()) { // For security reasons, only allow JS requests to be made on the frame that contains the plug-in. - if (frame->tree().find(request->target()) != frame) { + if (frame->tree().find(request->target(), *frame) != frame) { // Let the plug-in know that its frame load failed. m_plugin->frameDidFail(request->requestID(), false); return; diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog index fdf0fb35952d..083c770b3cc9 100644 --- a/Source/WebKitLegacy/mac/ChangeLog +++ b/Source/WebKitLegacy/mac/ChangeLog @@ -1,3 +1,13 @@ +2018-10-15 Chris Dumez + + Restrict browsing context lookup by name to frames that are related to one another + https://bugs.webkit.org/show_bug.cgi?id=190475 + + Reviewed by Alex Christensen. + + * WebView/WebFrame.mm: + (-[WebFrame findFrameNamed:]): + 2018-10-15 Alex Christensen Remove InjectedBundle processing of back/forward lists diff --git a/Source/WebKitLegacy/mac/WebView/WebFrame.mm b/Source/WebKitLegacy/mac/WebView/WebFrame.mm index 37b33c810840..7262ce2af6e7 100644 --- a/Source/WebKitLegacy/mac/WebView/WebFrame.mm +++ b/Source/WebKitLegacy/mac/WebView/WebFrame.mm @@ -2587,7 +2587,7 @@ - (WebFrame *)findFrameNamed:(NSString *)name Frame* coreFrame = _private->coreFrame; if (!coreFrame) return nil; - return kit(coreFrame->tree().find(name)); + return kit(coreFrame->tree().find(name, *coreFrame)); } - (WebFrame *)parentFrame diff --git a/Source/WebKitLegacy/win/WebFrame.cpp b/Source/WebKitLegacy/win/WebFrame.cpp index ab2f69ee435b..ea3103f70cd3 100644 --- a/Source/WebKitLegacy/win/WebFrame.cpp +++ b/Source/WebKitLegacy/win/WebFrame.cpp @@ -732,7 +732,7 @@ HRESULT WebFrame::findFrameNamed(_In_ BSTR name, _COM_Outptr_opt_ IWebFrame** fr if (!coreFrame) return E_UNEXPECTED; - Frame* foundFrame = coreFrame->tree().find(AtomicString(name, SysStringLen(name))); + Frame* foundFrame = coreFrame->tree().find(AtomicString(name, SysStringLen(name)), *coreFrame); if (!foundFrame) return S_OK;