WebKit Bugzilla
Attachment 368757 Details for
Bug 197466
: Setting a frame's src to a javascript URL should not run it synchronously
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-197466-20190501210130.patch (text/plain), 41.49 KB, created by
Chris Dumez
on 2019-05-01 21:01:30 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Chris Dumez
Created:
2019-05-01 21:01:30 PDT
Size:
41.49 KB
patch
obsolete
>Subversion Revision: 244861 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 1f7b771dc02236fcb438311c22a10757840efccf..d9030949e9c244328b109570aaf190c85bea9727 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,28 @@ >+2019-05-01 Chris Dumez <cdumez@apple.com> >+ >+ Setting a frame's src to a javascript URL should not run it synchronously >+ https://bugs.webkit.org/show_bug.cgi?id=197466 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ When an iframe's src attribute is set to a javascript URL, whether when parsing >+ or later on via JS, we now execute the URL's JavaScript asynchronously. We used >+ to execute it asynchronously, which was a source of security bugs and also did >+ not match other browsers. >+ >+ I have verified that our new behavior is aligned with both Firefox and Chrome. >+ >+ Test: fast/dom/frame-src-javascript-url-async.html >+ >+ * loader/NavigationScheduler.cpp: >+ (WebCore::ScheduledLocationChange::ScheduledLocationChange): >+ (WebCore::ScheduledLocationChange::~ScheduledLocationChange): >+ (WebCore::NavigationScheduler::scheduleLocationChange): >+ * loader/NavigationScheduler.h: >+ (WebCore::NavigationScheduler::scheduleLocationChange): >+ * loader/SubframeLoader.cpp: >+ (WebCore::SubframeLoader::requestFrame): >+ > 2019-05-01 Youenn Fablet <youenn@apple.com> > > Add back hasNullReferences() assert in Document::updateIsPlayingMedia >diff --git a/Source/WebCore/loader/NavigationScheduler.cpp b/Source/WebCore/loader/NavigationScheduler.cpp >index 617dedbfdfa865193c7b734d3bad5df55113d969..140e67b72b8b1799d4dadc9586f1194f9ea491a0 100644 >--- a/Source/WebCore/loader/NavigationScheduler.cpp >+++ b/Source/WebCore/loader/NavigationScheduler.cpp >@@ -193,18 +193,34 @@ public: > > class ScheduledLocationChange : public ScheduledURLNavigation { > public: >- ScheduledLocationChange(Document& initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad) >- : ScheduledURLNavigation(initiatingDocument, 0.0, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, true) { } >+ ScheduledLocationChange(Document& initiatingDocument, SecurityOrigin* securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, bool duringLoad, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL, CompletionHandler<void()>&& whenDone) >+ : ScheduledURLNavigation(initiatingDocument, 0.0, securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, true) >+ , m_shouldReplaceDocumentIfJavaScriptURL(shouldReplaceDocumentIfJavaScriptURL) >+ , m_whenDone(WTFMove(whenDone)) >+ { >+ } >+ >+ ~ScheduledLocationChange() >+ { >+ if (m_whenDone) >+ m_whenDone(); >+ } > > void fire(Frame& frame) override > { > UserGestureIndicator gestureIndicator { userGestureToForward() }; > > ResourceRequest resourceRequest { url(), referrer(), ResourceRequestCachePolicy::UseProtocolCachePolicy }; >- FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs(), initiatedByMainFrame() }; >+ FrameLoadRequest frameLoadRequest { initiatingDocument(), *securityOrigin(), resourceRequest, "_self", lockHistory(), lockBackForwardList(), MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, shouldOpenExternalURLs(), initiatedByMainFrame(), m_shouldReplaceDocumentIfJavaScriptURL }; > >+ auto whenDone = WTFMove(m_whenDone); > frame.loader().changeLocation(WTFMove(frameLoadRequest)); >+ whenDone(); > } >+ >+private: >+ ShouldReplaceDocumentIfJavaScriptURL m_shouldReplaceDocumentIfJavaScriptURL { ReplaceDocumentIfJavaScriptURL }; >+ CompletionHandler<void()> m_whenDone; > }; > > class ScheduledRefresh : public ScheduledURLNavigation { >@@ -405,10 +421,10 @@ LockBackForwardList NavigationScheduler::mustLockBackForwardList(Frame& targetFr > return LockBackForwardList::No; > } > >-void NavigationScheduler::scheduleLocationChange(Document& initiatingDocument, SecurityOrigin& securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList) >+void NavigationScheduler::scheduleLocationChange(Document& initiatingDocument, SecurityOrigin& securityOrigin, const URL& url, const String& referrer, LockHistory lockHistory, LockBackForwardList lockBackForwardList, ShouldReplaceDocumentIfJavaScriptURL shouldReplaceDocumentIfJavaScriptURL, CompletionHandler<void()>&& whenDone) > { > if (!shouldScheduleNavigation(url)) >- return; >+ return whenDone(); > > if (lockBackForwardList == LockBackForwardList::No) > lockBackForwardList = mustLockBackForwardList(m_frame); >@@ -424,14 +440,14 @@ void NavigationScheduler::scheduleLocationChange(Document& initiatingDocument, S > > FrameLoadRequest frameLoadRequest { initiatingDocument, securityOrigin, resourceRequest, "_self"_s, lockHistory, lockBackForwardList, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, initiatingDocument.shouldOpenExternalURLsPolicyToPropagate(), initiatedByMainFrame }; > loader.changeLocation(WTFMove(frameLoadRequest)); >- return; >+ return whenDone(); > } > > // Handle a location change of a page with no document as a special case. > // This may happen when a frame changes the location of another frame. > bool duringLoad = !loader.stateMachine().committedFirstRealDocumentLoad(); > >- schedule(std::make_unique<ScheduledLocationChange>(initiatingDocument, &securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad)); >+ schedule(std::make_unique<ScheduledLocationChange>(initiatingDocument, &securityOrigin, url, referrer, lockHistory, lockBackForwardList, duringLoad, shouldReplaceDocumentIfJavaScriptURL, WTFMove(whenDone))); > } > > void NavigationScheduler::scheduleFormSubmission(Ref<FormSubmission>&& submission) >diff --git a/Source/WebCore/loader/NavigationScheduler.h b/Source/WebCore/loader/NavigationScheduler.h >index b97d98681618eab60fd2758ad98993b245244982..aa41a6f27b73b267d34a2f7bd61231a760f20a72 100644 >--- a/Source/WebCore/loader/NavigationScheduler.h >+++ b/Source/WebCore/loader/NavigationScheduler.h >@@ -53,7 +53,7 @@ public: > bool locationChangePending(); > > void scheduleRedirect(Document& initiatingDocument, double delay, const URL&); >- void scheduleLocationChange(Document& initiatingDocument, SecurityOrigin&, const URL&, const String& referrer, LockHistory = LockHistory::Yes, LockBackForwardList = LockBackForwardList::Yes); >+ void scheduleLocationChange(Document& initiatingDocument, SecurityOrigin&, const URL&, const String& referrer, LockHistory = LockHistory::Yes, LockBackForwardList = LockBackForwardList::Yes, ShouldReplaceDocumentIfJavaScriptURL = ReplaceDocumentIfJavaScriptURL, CompletionHandler<void()>&& whenDone = [] { }); > void scheduleFormSubmission(Ref<FormSubmission>&&); > void scheduleRefresh(Document& initiatingDocument); > void scheduleHistoryNavigation(int steps); >diff --git a/Source/WebCore/loader/SubframeLoader.cpp b/Source/WebCore/loader/SubframeLoader.cpp >index 1f90a83c779598bc083b245bf5f5fecb9a81e485..a269587c908af4c74a3e2c8e973e7b5ced6ba855 100644 >--- a/Source/WebCore/loader/SubframeLoader.cpp >+++ b/Source/WebCore/loader/SubframeLoader.cpp >@@ -56,6 +56,7 @@ > #include "SecurityOrigin.h" > #include "SecurityPolicy.h" > #include "Settings.h" >+#include <wtf/CompletionHandler.h> > > namespace WebCore { > >@@ -86,17 +87,22 @@ bool SubframeLoader::requestFrame(HTMLFrameOwnerElement& ownerElement, const Str > if (shouldConvertInvalidURLsToBlank() && !url.isValid()) > url = WTF::blankURL(); > >- bool hasExistingFrame = ownerElement.contentFrame(); >+ // If we will schedule a javascript URL load, we delay the firing of the load event at least until we've run the javascript URL. >+ bool shouldDelayLoadEvent = !scriptURL.isEmpty(); >+ CompletionHandlerCallingScope stopDelayingLoadEvent; >+ if (shouldDelayLoadEvent) { >+ ownerElement.document().incrementLoadEventDelayCount(); >+ stopDelayingLoadEvent = CompletionHandlerCallingScope([ownerDocument = makeRef(ownerElement.document())] { >+ ownerDocument->decrementLoadEventDelayCount(); >+ }); >+ } >+ > Frame* frame = loadOrRedirectSubframe(ownerElement, url, frameName, lockHistory, lockBackForwardList); > if (!frame) > return false; > >- // If we create a new subframe then an empty document is loaded into it synchronously and may >- // cause script execution (say, via a DOM load event handler) that can do anything, including >- // navigating the subframe. We only want to evaluate scriptURL if the frame has not been navigated. >- bool canExecuteScript = hasExistingFrame || (frame->loader().documentLoader() && frame->loader().documentLoader()->originalURL() == WTF::blankURL()); >- if (!scriptURL.isEmpty() && canExecuteScript && ownerElement.isURLAllowed(scriptURL)) >- frame->script().executeIfJavaScriptURL(scriptURL); >+ if (!scriptURL.isEmpty() && ownerElement.isURLAllowed(scriptURL)) >+ frame->navigationScheduler().scheduleLocationChange(ownerElement.document(), ownerElement.document().securityOrigin(), scriptURL, m_frame.loader().outgoingReferrer(), lockHistory, lockBackForwardList, DoNotReplaceDocumentIfJavaScriptURL, stopDelayingLoadEvent.release()); > > return true; > } >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index b7cec96e8b441a03826b364bec25aa37f31102e0..831a16962cf48459bb169c06b309e82a98533d7a 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,48 @@ >+2019-05-01 Chris Dumez <cdumez@apple.com> >+ >+ Setting a frame's src to a javascript URL should not run it synchronously >+ https://bugs.webkit.org/show_bug.cgi?id=197466 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * fast/dom/frame-src-javascript-url-async-expected.txt: Added. >+ * fast/dom/frame-src-javascript-url-async.html: Added. >+ Add layout test coverage for the fact that the javascript URL is executed asynchronously >+ whether set during parsing or later via JS. Also makes sure that executing the javascript >+ URL asynchronously does not replace the frame's window. This test passes in both Chrome >+ and Firefox. >+ >+ * imported/blink/fast/frames/navigation-in-pagehide.html: >+ Re-sync this test from the Blink repository. >+ >+ * fast/dom/Element/id-in-frameset-expected.txt: >+ * fast/dom/insertedIntoDocument-iframe-expected.txt: >+ * fast/dom/javascript-url-exception-isolation-expected.txt: >+ * fast/dom/javascript-url-exception-isolation.html: >+ * fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt: >+ * fast/dom/resources/javascript-url-crash-function-iframe.html: >+ * fast/frames/adopt-from-created-document.html: >+ * fast/frames/out-of-document-iframe-has-child-frame.html: >+ * fast/loader/javascript-url-iframe-remove-on-navigate-async-delegate.html: >+ * fast/loader/javascript-url-iframe-remove-on-navigate.html: >+ * fast/loader/nested-document-handling.html: >+ * fast/loader/unload-mutation-crash.html: >+ * fast/parser/resources/set-parent-to-javascript-url.html: >+ * fast/parser/xml-error-adopted.xml: >+ * http/tests/navigation/lockedhistory-iframe-expected.txt: >+ * http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt: >+ * http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt: >+ * http/tests/security/contentSecurityPolicy/javascript-url-blocked-by-default-src-star-expected.txt: >+ * http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt: >+ * http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html: >+ * http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html: >+ * imported/blink/loader/iframe-sync-loads-expected.txt: >+ * js/dom/call-base-resolution.html: >+ * platform/wk2/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt: >+ * webarchive/loading/javascript-url-iframe-crash-expected.txt: >+ Update / Rebaseline existing tests to reflect behavior change. I ran those tests in Firefox and Chrome to confirm that our behavior >+ is indeed aligned. >+ > 2019-05-01 Devin Rousso <drousso@apple.com> > > Unreviewed, fix test failures after r242809. >diff --git a/LayoutTests/fast/dom/Element/id-in-frameset-expected.txt b/LayoutTests/fast/dom/Element/id-in-frameset-expected.txt >index b3db1a3144239a274e47deb52f78c46ac112f360..a71080b1b06051e6f4ed184866e3ca75aacb438e 100644 >--- a/LayoutTests/fast/dom/Element/id-in-frameset-expected.txt >+++ b/LayoutTests/fast/dom/Element/id-in-frameset-expected.txt >@@ -1,2 +1,2 @@ >-ALERT: 1 >+ALERT: 2 > >diff --git a/LayoutTests/fast/dom/Element/id-in-frameset.html b/LayoutTests/fast/dom/Element/id-in-frameset.html >index 79165352966b9a7ea2a7721938a1942a302b96bb..9b632037d999927a5ebeb87e9034c0dca4120e7c 100644 >--- a/LayoutTests/fast/dom/Element/id-in-frameset.html >+++ b/LayoutTests/fast/dom/Element/id-in-frameset.html >@@ -1,5 +1,10 @@ > <html> >- >+<script> >+if (window.testRunner) { >+ testRunner.dumpAsText(); >+ testRunner.waitUntilDone(); >+} >+</script> > <frameset id="frameset"> > <frame name="frame2" src="about:blank"> > <frame name="frame1" src="javascript: >@@ -16,6 +21,8 @@ > > top.frameset.removeChild(top.frame2.frameElement); > log(top.frameset.children.length); >+ if (window.testRunner) >+ testRunner.notifyDone(); > "> > > <frame name="frame3" src="about:blank"> >diff --git a/LayoutTests/fast/dom/frame-src-javascript-url-async-expected.txt b/LayoutTests/fast/dom/frame-src-javascript-url-async-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b472de68a88ebf1cfac1fa968e14da10f24bcd67 >--- /dev/null >+++ b/LayoutTests/fast/dom/frame-src-javascript-url-async-expected.txt >@@ -0,0 +1,13 @@ >+Checks that setting an iframe's src attribute to a javascript URL runs the javascript asynchronously >+ >+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >+ >+ >+PASS frame2.contentWindow is frame2Window >+PASS messages is "1234" >+PASS frame1.contentWindow is frame1Window >+PASS frame2.contentWindow is frame2Window >+PASS successfullyParsed is true >+ >+TEST COMPLETE >+ >diff --git a/LayoutTests/fast/dom/frame-src-javascript-url-async.html b/LayoutTests/fast/dom/frame-src-javascript-url-async.html >new file mode 100644 >index 0000000000000000000000000000000000000000..feed442540053e0448f394a02833a7a2ee90cc38 >--- /dev/null >+++ b/LayoutTests/fast/dom/frame-src-javascript-url-async.html >@@ -0,0 +1,35 @@ >+<!DOCTYPE html> >+<html> >+<body> >+<script src="../../resources/js-test.js"></script> >+<script> >+description("Checks that setting an iframe's src attribute to a javascript URL runs the javascript asynchronously"); >+jsTestIsAsync = true; >+ >+let messages = ""; >+const expectedMessageCount = 4; >+function log(msg) >+{ >+ messages += msg; >+ if (messages.length == expectedMessageCount) { >+ shouldBeEqualToString("messages", "1234"); >+ shouldBe("frame1.contentWindow", "initialFrame1Window"); >+ shouldBe("frame2.contentWindow", "frame2Window"); >+ finishJSTest(); >+ } >+} >+</script> >+<iframe id="frame1" src="javascript:parent.log('3')"></iframe> >+<iframe id="frame2"></iframe> >+<script> >+frame1 = document.getElementById("frame1"); >+frame2 = document.getElementById("frame2"); >+initialFrame1Window = frame1.contentWindow; >+frame2Window = frame2.contentWindow; >+log('1'); >+frame2.src = "javascript:parent.log('4')"; >+shouldBe("frame2.contentWindow", "frame2Window"); >+log('2'); >+</script> >+</body> >+</html> >diff --git a/LayoutTests/fast/dom/insertedIntoDocument-iframe-expected.txt b/LayoutTests/fast/dom/insertedIntoDocument-iframe-expected.txt >index 7ef22e9a431ad0272713b71fdc8794016c8ef12f..6e1f6dfd9e683ba9d5c143601a02cd9559b41022 100644 >--- a/LayoutTests/fast/dom/insertedIntoDocument-iframe-expected.txt >+++ b/LayoutTests/fast/dom/insertedIntoDocument-iframe-expected.txt >@@ -1 +1,3 @@ >+CONSOLE MESSAGE: line 1: TypeError: Argument 1 ('child') to Node.removeChild must be an instance of Node > PASS >+ >diff --git a/LayoutTests/fast/dom/javascript-url-exception-isolation-expected.txt b/LayoutTests/fast/dom/javascript-url-exception-isolation-expected.txt >index 51b343549ee00917506df61e80cd7de96dad0533..b7485a1ef6b405b2bca9dfa88f68d2ec6da3ca11 100644 >--- a/LayoutTests/fast/dom/javascript-url-exception-isolation-expected.txt >+++ b/LayoutTests/fast/dom/javascript-url-exception-isolation-expected.txt >@@ -1,5 +1,5 @@ > CONSOLE MESSAGE: line 1: 42 >-CONSOLE MESSAGE: line 25: SyntaxError: Unexpected token '<' >+CONSOLE MESSAGE: line 1: SyntaxError: Unexpected token '<' > Exceptions thrown in javascript URLs should not propagate to the main script. > > On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >diff --git a/LayoutTests/fast/dom/javascript-url-exception-isolation.html b/LayoutTests/fast/dom/javascript-url-exception-isolation.html >index 6f39b2cb9a6d49678e6d9b5f57da2d421b61eb54..66dad1cf323fb697fa4ff229f79484b6eab8aa70 100644 >--- a/LayoutTests/fast/dom/javascript-url-exception-isolation.html >+++ b/LayoutTests/fast/dom/javascript-url-exception-isolation.html >@@ -20,9 +20,12 @@ try { > } > shouldBeFalse('caughtException'); > >+var subframe2 = document.createElement("iframe"); >+document.body.appendChild(subframe2); >+ > // Compile-time exception. > try { >- subframe.src = 'javascript:<html></html>'; >+ subframe2.src = 'javascript:<html></html>'; > } catch(e) { > caughtException = true; > } >diff --git a/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt b/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt >index e96375ae81dd325312539c7f7baaf00110a34678..2cb8efa3c999384db53890d6ee9796972bb8c229 100644 >--- a/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt >+++ b/LayoutTests/fast/dom/no-assert-for-malformed-js-url-attribute-expected.txt >@@ -1,4 +1,4 @@ >-CONSOLE MESSAGE: line 14: SyntaxError: Unexpected identifier 'orem' >+CONSOLE MESSAGE: line 1: SyntaxError: Unexpected identifier 'orem' > This tests that we do not assert when a malformed JS URL is passed to the 'src' attribute of an iframe. The test passes if it does not ASSERT. > > On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". >diff --git a/LayoutTests/fast/dom/resources/javascript-url-crash-function-iframe.html b/LayoutTests/fast/dom/resources/javascript-url-crash-function-iframe.html >index 1d6a49d827fa53a94e728e8dbe6db0f266bdccbd..0a0154c4c25243032a8db7bfd498af4aef22fd9f 100644 >--- a/LayoutTests/fast/dom/resources/javascript-url-crash-function-iframe.html >+++ b/LayoutTests/fast/dom/resources/javascript-url-crash-function-iframe.html >@@ -16,7 +16,9 @@ function test() > setTimeout(function () > { > test(); >- if (window.testRunner) >- testRunner.notifyDone(); >+ top.setTimeout(() => { >+ if (window.testRunner) >+ testRunner.notifyDone(); >+ }, 0); > }, 0); > </script> >diff --git a/LayoutTests/fast/frames/adopt-from-created-document.html b/LayoutTests/fast/frames/adopt-from-created-document.html >index 2a9829b0c0e0ef20b3b97c6303c324a9460808af..33855d562b30a5d65c9231a3f181e4da39552184 100644 >--- a/LayoutTests/fast/frames/adopt-from-created-document.html >+++ b/LayoutTests/fast/frames/adopt-from-created-document.html >@@ -8,10 +8,10 @@ var doc = document.implementation.createDocument('http://www.w3.org/1999/xhtml', > alert(2); > var ifr = doc.createElement('iframe'); > alert(3); >-ifr.setAttribute('src', 'javascript:alert(6)'); >+ifr.setAttribute('src', 'javascript:alert(7)'); > alert(4); > var adopted = document.adoptNode(ifr) > alert(5); > document.body.appendChild(adopted); >-alert(7); >+alert(6); > </script> >diff --git a/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html b/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html >index e9e576beec0682c7e93d200ce413b78bf3184f5e..8db38d75be7e38279de7ff621c5cab2881a2d292 100644 >--- a/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html >+++ b/LayoutTests/fast/frames/out-of-document-iframe-has-child-frame.html >@@ -1,12 +1,13 @@ > <html> > <head> >-<script src="../../resources/js-test-pre.js"></script> >+<script src="../../resources/js-test.js"></script> > </head> > <body> > <div id="main"/> > <script> > description("This tests that several ways of making an iframe that isn't inserted into a document tree" > + " but has a child frame will fail."); >+jsTestIsAsync = true; > > main = document.getElementById("main"); > >@@ -44,9 +45,11 @@ try { > helperFrame.src = "javascript:top.container.removeChild(top.targetFrame3)"; > document.body.appendChild(container); > } catch (e) { } >-shouldBeTrue("targetFrame3.contentWindow == undefined"); > >-isSuccessfullyParsed(); >+setTimeout(() => { >+ shouldBeTrue("targetFrame3.contentWindow == undefined"); >+ finishJSTest(); >+}, 0); > </script> > </body> > </html> >diff --git a/LayoutTests/fast/loader/javascript-url-iframe-remove-on-navigate-async-delegate.html b/LayoutTests/fast/loader/javascript-url-iframe-remove-on-navigate-async-delegate.html >index a3f633c73c8128a32ccf5be65da073a9868d091c..73fcd763c2b8329ce1e91942e335a79f1d39a023 100644 >--- a/LayoutTests/fast/loader/javascript-url-iframe-remove-on-navigate-async-delegate.html >+++ b/LayoutTests/fast/loader/javascript-url-iframe-remove-on-navigate-async-delegate.html >@@ -8,13 +8,14 @@ if (window.testRunner) { > } > > let frame = document.getElementById("target"); >-frame.contentWindow.onbeforeunload = function() { >- setTimeout(function() { >- frame.src = "javascript:alert('FAIL')"; >- }, 0); >-}; > > window.addEventListener("load", function() { >+ frame.contentWindow.onbeforeunload = function() { >+ setTimeout(function() { >+ frame.src = "javascript:alert('FAIL')"; >+ }, 0); >+ }; >+ > document.write("PASS - Javascript URL blocked without crashing."); > if (window.testRunner) > testRunner.notifyDone(); >diff --git a/LayoutTests/fast/loader/javascript-url-iframe-remove-on-navigate.html b/LayoutTests/fast/loader/javascript-url-iframe-remove-on-navigate.html >index af3764dfdc2b91185ca38528cfd932ee1a4f5506..25944576b4945b11d72c0adbb916d0801a13b55c 100644 >--- a/LayoutTests/fast/loader/javascript-url-iframe-remove-on-navigate.html >+++ b/LayoutTests/fast/loader/javascript-url-iframe-remove-on-navigate.html >@@ -6,13 +6,13 @@ if (window.testRunner) { > } > > let frame = document.getElementById("target"); >-frame.contentWindow.onbeforeunload = function() { >- setTimeout(function() { >- frame.src = "javascript:alert('FAIL')"; >- }, 0); >-}; > > window.addEventListener("load", function() { >+ frame.contentWindow.onbeforeunload = function() { >+ setTimeout(function() { >+ frame.src = "javascript:alert('FAIL')"; >+ }, 0); >+ }; > document.write("PASS - Javascript URL blocked without crashing."); > if (window.testRunner) > testRunner.notifyDone(); >diff --git a/LayoutTests/fast/loader/nested-document-handling.html b/LayoutTests/fast/loader/nested-document-handling.html >index 3e81697d5376584a34f2fe19e648736de5a3b999..ec9077708aabd4f9598b02b2bf7a1c3582438dfd 100644 >--- a/LayoutTests/fast/loader/nested-document-handling.html >+++ b/LayoutTests/fast/loader/nested-document-handling.html >@@ -24,25 +24,27 @@ function runTest() { > aFrame.contentWindow.onunload = () => { > topFrame.src = "javascript:''"; > >- let bFrame = topFrame.contentDocument.appendChild(document.createElement("iframe")); >- bFrame.id = 'bFrame'; >+ topFrame.onload = () => { >+ let bFrame = topFrame.contentDocument.body.appendChild(document.createElement("iframe")); >+ bFrame.id = 'bFrame'; > >- bFrame.contentWindow.onunload = () => { >- topFrame.src = "javascript:''"; >+ bFrame.contentWindow.onunload = () => { >+ topFrame.src = "javascript:''"; > >- let doc = topFrame.contentDocument; >+ let doc = topFrame.contentDocument; > >- topFrame.onload = () => { > topFrame.onload = () => { >- topFrame.onload = null; >- let s = doc.createElement("form"); >- s.action = "javascript:alert(location)"; >- s.submit(); >+ topFrame.onload = () => { >+ topFrame.onload = null; >+ let s = doc.createElement("form"); >+ s.action = "javascript:alert(location)"; >+ s.submit(); >+ }; >+ >+ topFrame.src = "resources/subframe-success.html"; > }; >- >- topFrame.src = "resources/subframe-success.html"; > }; >- >+ topFrame.src = "javascript:''"; > }; > }; > >@@ -52,4 +54,4 @@ function runTest() { > </head> > <body onload="runTest()"> > </body> >-</html> >\ No newline at end of file >+</html> >diff --git a/LayoutTests/fast/loader/unload-mutation-crash.html b/LayoutTests/fast/loader/unload-mutation-crash.html >index 246fe169227785b1d6189140a6fe1ba63941190e..c78db43d468308d1d502219f5e2dc6bde5ff8b03 100644 >--- a/LayoutTests/fast/loader/unload-mutation-crash.html >+++ b/LayoutTests/fast/loader/unload-mutation-crash.html >@@ -2,8 +2,10 @@ > <html> > <head> > <script> >-if (window.testRunner) >- window.testRunner.dumpAsText(); >+if (window.testRunner) { >+ testRunner.dumpAsText(); >+ testRunner.waitUntilDone(); >+} > > function start() { > window.firstFrame = document.createElement('iframe'); >@@ -20,6 +22,8 @@ function maybeStart() { > > window.firstFrame.src = 'javascript:"";'; > document.write("PASS. WebKit didn't crash."); >+ if (window.testRunner) >+ testRunner.notifyDone(); > } > </script> > </head> >diff --git a/LayoutTests/fast/parser/resources/set-parent-to-javascript-url.html b/LayoutTests/fast/parser/resources/set-parent-to-javascript-url.html >index 71d78bf68f30ed04aba14779fd8376b5460fedb7..4f1ebdd03015bb3225d30ec8560623ef9704495a 100644 >--- a/LayoutTests/fast/parser/resources/set-parent-to-javascript-url.html >+++ b/LayoutTests/fast/parser/resources/set-parent-to-javascript-url.html >@@ -1,7 +1,7 @@ > <script> > const parent = window.parent; > alert(1); >-parent.document.getElementsByTagName('iframe')[0].src = "javascript:alert(2),'PASS<script>alert(3)<\/script>'"; >-alert(4); >+parent.document.getElementsByTagName('iframe')[0].src = "javascript:alert(3),'PASS<script>alert(4)<\/script>'"; >+alert(2); > parent.setTimeout("done()", 0); > </script> >diff --git a/LayoutTests/fast/parser/xml-error-adopted.xml b/LayoutTests/fast/parser/xml-error-adopted.xml >index 9b1abeb1d42f14061666ee2b04eef27d1ef6e0fd..f3e97ff58ae33d5d1a3b85b0deee8768d28252db 100644 >--- a/LayoutTests/fast/parser/xml-error-adopted.xml >+++ b/LayoutTests/fast/parser/xml-error-adopted.xml >@@ -15,7 +15,9 @@ function test() { > testRunner.notifyDone(); > } > >-setTimeout(test, 0); >+onload = () => { >+ setTimeout(test, 0); >+}; > </script> > <elt attr="1" attr="2"/> >-</svg> >\ No newline at end of file >+</svg> >diff --git a/LayoutTests/http/tests/navigation/lockedhistory-iframe-expected.txt b/LayoutTests/http/tests/navigation/lockedhistory-iframe-expected.txt >index 558eca86eb20decf7dd7a97c74672dd505ffca2d..8267def9b537995226a2b43c649f9e1afe062858 100644 >--- a/LayoutTests/http/tests/navigation/lockedhistory-iframe-expected.txt >+++ b/LayoutTests/http/tests/navigation/lockedhistory-iframe-expected.txt >@@ -4,5 +4,6 @@ This test verifies that setting the iframe.src through javascript to # does not > > ============== Back Forward List ============== > curr-> http://127.0.0.1:8000/navigation/lockedhistory-iframe.html **nav target** >- about:blank (in frame "<!--frame1-->") >+ http://127.0.0.1:8000/navigation/lockedhistory-iframe.html# (in frame "<!--frame1-->") >+ about:blank (in frame "<!--frame2-->") > =============================================== >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt >index 8c43c1895bd5e3eafa0db96b8658c6843289805b..ae41c506a3b2a52a9e5f540ef306a2bbf3bf7c17 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt >@@ -6,8 +6,9 @@ frame "<!--frame2-->" - didCommitLoadForFrame > frame "<!--frame2-->" - didFinishDocumentLoadForFrame > frame "<!--frame2-->" - didHandleOnloadEventsForFrame > frame "<!--frame2-->" - didFinishLoadForFrame >-CONSOLE MESSAGE: Blocked mixed content http://127.0.0.1:8000/security/resources/compass.jpg because 'block-all-mixed-content' appears in the Content Security Policy. >+frame "<!--frame2-->" - willPerformClientRedirectToURL: javascript:document.write('%3Cimg%20src=%22http://127.0.0.1:8000/security/resources/compass.jpg%22%3E'); > frame "<!--frame1-->" - didFinishDocumentLoadForFrame >+CONSOLE MESSAGE: Blocked mixed content http://127.0.0.1:8000/security/resources/compass.jpg because 'block-all-mixed-content' appears in the Content Security Policy. > frame "<!--frame1-->" - didFinishLoadForFrame > main frame - didFinishLoadForFrame > This test loads a secure iframe that loads an insecure image inside a JavaScript URL iframe. We should trigger a mixed content block because the child frame has CSP directive block-all-mixed-content and a JavaScript URL executes in the same origin as its embedding document. >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt >index ef6629340bb74a63eedb06c68534ac492b527c25..3a1a9f47466e6f721717410e41ed23cc980d7b8f 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-allowed-expected.txt >@@ -1,7 +1,7 @@ > CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect. > CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect. > CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect. >-ALERT: PASS > CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect. > CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect. >+ALERT: PASS > >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-by-default-src-star-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-by-default-src-star-expected.txt >index c64af31b86bfd114ae96bceedc3c435e9d21374f..f295915cd66236df17d9494ce2d890e23c8d87ec 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-by-default-src-star-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-by-default-src-star-expected.txt >@@ -1,4 +1,4 @@ >-CONSOLE MESSAGE: line 1: Refused to execute a script because its hash, its nonce, or 'unsafe-inline' appears in neither the script-src directive nor the default-src directive of the Content Security Policy. > CONSOLE MESSAGE: Refused to load javascript:alert('FAIL'); because it appears in neither the object-src directive nor the default-src directive of the Content Security Policy. > CONSOLE MESSAGE: Refused to load javascript:alert('FAIL'); because it appears in neither the object-src directive nor the default-src directive of the Content Security Policy. >+CONSOLE MESSAGE: line 1: Refused to execute a script because its hash, its nonce, or 'unsafe-inline' appears in neither the script-src directive nor the default-src directive of the Content Security Policy. > >diff --git a/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt b/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt >index 967bfa63956f895c231b4b262927347ffa7d4edb..7e1a9197a20dc3efdb1d5904adcc2c88ae1d4fe2 100644 >--- a/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt >+++ b/LayoutTests/http/tests/security/contentSecurityPolicy/javascript-url-blocked-expected.txt >@@ -1,7 +1,7 @@ > CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect. > CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect. > CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect. >-CONSOLE MESSAGE: line 1: Refused to execute a script because its hash, its nonce, or 'unsafe-inline' does not appear in the script-src directive of the Content Security Policy. > CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect. > CONSOLE MESSAGE: The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect. >+CONSOLE MESSAGE: line 1: Refused to execute a script because its hash, its nonce, or 'unsafe-inline' does not appear in the script-src directive of the Content Security Policy. > >diff --git a/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html b/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html >index 85ab9be7b72d4e7cb11040ece66d340f10030fc6..236042a0f11cb87e4e306a0eca4cc98f8fee9a92 100644 >--- a/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html >+++ b/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame-2-level.html >@@ -7,11 +7,13 @@ > if (window.testRunner) { > testRunner.dumpAsText(); > testRunner.dumpChildFramesAsText(); >+ testRunner.waitUntilDone(); > } > > var innerURL = 'javascript:\\\"<html>' > + "<scr" + "ipt>" > + 'top.document.getElementById(\\\\\\\"accessMe\\\\\\\").innerHTML = \\\\\\\"PASS: Cross frame access from a javascript: URL inside another javascript: URL was allowed!\\\\\\\";' >+ + 'top.setTimeout(() => { testRunner.notifyDone(); }, 0);' > + "</scri" + "pt>" > + "<body>" > + "<p>Inner-inner iframe.</p>" >diff --git a/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html b/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html >index ce83c723a2228df329da3935e41b557bca450ba4..b94cd4e782cf9149d79c69debe400f9130dfa96a 100644 >--- a/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html >+++ b/LayoutTests/http/tests/security/javascriptURL/xss-ALLOWED-from-javascript-url-sub-frame.html >@@ -7,6 +7,7 @@ > if (window.testRunner) { > testRunner.dumpAsText(); > testRunner.dumpChildFramesAsText(); >+ testRunner.waitUntilDone(); > } > > var url = "javascript:\"<html>" >@@ -20,6 +21,12 @@ > > var iframe = document.getElementById("aFrame"); > iframe.src = url; >+ onload = () => { >+ setTimeout(() => { >+ if (window.testRunner) >+ testRunner.notifyDone(); >+ }); >+ } > </script> > </body> > </html> >diff --git a/LayoutTests/imported/blink/fast/frames/navigation-in-pagehide.html b/LayoutTests/imported/blink/fast/frames/navigation-in-pagehide.html >index 37c2149459c445850dba7d16df791483644ce9c3..feca0959f2bb4d09de9e685ef6b477d6ad4c6365 100644 >--- a/LayoutTests/imported/blink/fast/frames/navigation-in-pagehide.html >+++ b/LayoutTests/imported/blink/fast/frames/navigation-in-pagehide.html >@@ -17,20 +17,13 @@ function start() { > var div = document.createElement('div'); > firstFrame.appendChild(div); > secondFrame = document.createElement('iframe'); >- secondFrame.src = 'javascript:window.top.maybeStart();'; >+ secondFrame.src = 'javascript:window.top.reallyStart();'; > div.appendChild(secondFrame); > var firstFrameRoot = firstFrame.contentDocument.documentElement; > document.documentElement.appendChild(div); > firstFrameRoot.appendChild(secondFrame); > } > >-function maybeStart() { >- if (callbackCount++ > 1) { >- reallyStart(); >- return; >- } >-} >- > function reallyStart(frame) { > secondFrame.contentWindow.onpagehide = function () { > firstFrame.src = 'javascript:window.top.navigateThere();'; >@@ -39,7 +32,7 @@ function reallyStart(frame) { > > if (window.location.hash == '#done') { > if (window.testRunner) >- window.testRunner.notifyDone(); >+ testRunner.notifyDone(); > return; > } > >diff --git a/LayoutTests/imported/blink/loader/iframe-sync-loads-expected.txt b/LayoutTests/imported/blink/loader/iframe-sync-loads-expected.txt >index 1159c11eb9ee633392ee88439ef20e898cadb452..686d3b3ecf2e26adc3d0ab4fb52583e7a6c6d16e 100644 >--- a/LayoutTests/imported/blink/loader/iframe-sync-loads-expected.txt >+++ b/LayoutTests/imported/blink/loader/iframe-sync-loads-expected.txt >@@ -1,4 +1,4 @@ >- sync : src = javascript:"content" >+ASYNC : src = javascript:"content" > ASYNC : src = data:text/html,content > ASYNC : srcdoc = "content" > done >diff --git a/LayoutTests/js/dom/call-base-resolution.html b/LayoutTests/js/dom/call-base-resolution.html >index c131bdb9be9079429d974244ea94a783deaeec50..4bdb08b04e113606a6ec886584c73ae5cbd8230e 100644 >--- a/LayoutTests/js/dom/call-base-resolution.html >+++ b/LayoutTests/js/dom/call-base-resolution.html >@@ -4,7 +4,7 @@ > </head> > <body> > >-<script src="../../resources/js-test-pre.js"></script> >+<script src="../../resources/js-test.js"></script> > <script> > window.name = "o"; > function f() { >@@ -77,7 +77,5 @@ > parent.testFailed(results + ' should be ' + expected + ', but was not.'); > "> > </iframe> >-<script src="../../resources/js-test-post.js"></script> >- > </body> > </html> >diff --git a/LayoutTests/platform/wk2/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt b/LayoutTests/platform/wk2/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt >index 147ccce9af984605926b46cbbb9450a2f5a3534f..8ec742d2964196e45c17bd94453a0417b9783f78 100644 >--- a/LayoutTests/platform/wk2/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt >+++ b/LayoutTests/platform/wk2/http/tests/security/contentSecurityPolicy/block-all-mixed-content/insecure-image-in-javascript-url-iframe-in-iframe-expected.txt >@@ -6,8 +6,9 @@ frame "<!--frame2-->" - didCommitLoadForFrame > frame "<!--frame2-->" - didFinishDocumentLoadForFrame > frame "<!--frame2-->" - didHandleOnloadEventsForFrame > frame "<!--frame2-->" - didFinishLoadForFrame >-CONSOLE MESSAGE: Blocked mixed content http://127.0.0.1:8000/security/resources/compass.jpg because 'block-all-mixed-content' appears in the Content Security Policy. >+frame "<!--frame2-->" - willPerformClientRedirectToURL: javascript:document.write('<img src=%22http://127.0.0.1:8000/security/resources/compass.jpg%22>'); > frame "<!--frame1-->" - didFinishDocumentLoadForFrame >+CONSOLE MESSAGE: Blocked mixed content http://127.0.0.1:8000/security/resources/compass.jpg because 'block-all-mixed-content' appears in the Content Security Policy. > frame "<!--frame1-->" - didFinishLoadForFrame > main frame - didFinishLoadForFrame > This test loads a secure iframe that loads an insecure image inside a JavaScript URL iframe. We should trigger a mixed content block because the child frame has CSP directive block-all-mixed-content and a JavaScript URL executes in the same origin as its embedding document. >diff --git a/LayoutTests/webarchive/loading/javascript-url-iframe-crash-expected.txt b/LayoutTests/webarchive/loading/javascript-url-iframe-crash-expected.txt >index da1c7a5574f051200ab55c6c064867f4e88b408c..cb980efea30757ae0e7e3de43cc121aaba1d9a7e 100644 >--- a/LayoutTests/webarchive/loading/javascript-url-iframe-crash-expected.txt >+++ b/LayoutTests/webarchive/loading/javascript-url-iframe-crash-expected.txt >@@ -11,9 +11,10 @@ frame "<!--frame1-->" - didCommitLoadForFrame > frame "<!--frame1-->" - didFinishDocumentLoadForFrame > frame "<!--frame1-->" - didHandleOnloadEventsForFrame > frame "<!--frame1-->" - didFinishLoadForFrame >+frame "<!--frame1-->" - willPerformClientRedirectToURL: javascript:'' >+main frame - didFinishDocumentLoadForFrame > frame "<!--frame1-->" - didFinishDocumentLoadForFrame > frame "<!--frame1-->" - didHandleOnloadEventsForFrame >-main frame - didFinishDocumentLoadForFrame > main frame - didHandleOnloadEventsForFrame > main frame - didFinishLoadForFrame > Loading this webarchive with a "non-empty javascript URL iframe" should not crash.
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 197466
:
368683
|
368689
|
368690
|
368691
|
368693
|
368699
|
368706
|
368709
|
368710
|
368719
|
368723
|
368725
|
368729
|
368732
|
368734
|
368736
|
368741
|
368742
|
368750
|
368751
|
368755
|
368756
|
368757
|
368758
|
368762
|
368763
|
368764
|
368765
|
368781
|
368786
|
368793
|
368796
|
368805
|
368807
|
368813
|
368821
|
368825