From 6cb3efffe3580368dac99b9c2be1a230ac3d2b0a Mon Sep 17 00:00:00 2001 From: "cdumez@apple.com" 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. git-svn-id: http://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 ed9c55d65d79c..573bf15771b0b 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 8e8704ae8b348..e135f52a4d55e 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 b6ece8b59a568..e6202cd46aadd 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 bb5d46eae397a..b3b59ba30cd4e 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 0000000000000..72a8dce01a8e9 --- /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 0000000000000..39f13986a6ca5 --- /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 0000000000000..a23c4000140f6 --- /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 0000000000000..7d0de75f0559d --- /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 0000000000000..63d7b07d0cabf --- /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 0000000000000..34f9c53b0bd83 --- /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 0000000000000..9cd97618f018e --- /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 0000000000000..d9c019bb24383 --- /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 0000000000000..9ebeb73aeb2f7 --- /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 0000000000000..842921c4d0386 --- /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 0000000000000..46f5dc4a4d09d --- /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 0000000000000..84ff71bab37f0 --- /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 0000000000000..8613a48b7320f --- /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 0000000000000..cb880ee6d1333 --- /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 ada1d16f0d670..0eb21f7709e22 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 8f6b7909992a2..6b109ebff0238 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 5c32e5e716030..caadabe8e3882 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 fea93dc809073..5c2abf37aa309 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 0b775619c3e2f..11ede65be80dc 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 067ed0ad60316..cba574fb97042 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 2945605369e5a..10d047a06b0a2 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 8403876a361f6..0beb28f664ece 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 42cb333a0c09d..a9fec153c9782 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 0b6a763528bfd..97c8f2b7a46ef 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 748eae3a33d8f..85eb798cd09fe 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 2b4f04dd83649..40db0080c112e 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 f0752bd982a15..75808b1b45b0e 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 fdf0fb35952dc..083c770b3cc9f 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 37b33c8108402..7262ce2af6e78 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 ab2f69ee435b1..ea3103f70cd39 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;