WebKit Bugzilla
Attachment 340230 Details for
Bug 185567
: X-Frame-Options: SAMEORIGIN needs to check all ancestor frames
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch and layout tests
bug-185567-20180511162633.patch (text/plain), 19.01 KB, created by
Daniel Bates
on 2018-05-11 16:26:34 PDT
(
hide
)
Description:
Patch and layout tests
Filename:
MIME Type:
Creator:
Daniel Bates
Created:
2018-05-11 16:26:34 PDT
Size:
19.01 KB
patch
obsolete
>Subversion Revision: 231707 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 2dc9d60260c227bb4692e653a249c974c5d053db..6aa91552b40cfbb16ce5771eda5260865953030f 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,30 @@ >+2018-05-11 Daniel Bates <dabates@apple.com> >+ >+ X-Frame-Options: SAMEORIGIN needs to check all ancestor frames >+ https://bugs.webkit.org/show_bug.cgi?id=185567 >+ <rdar://problem/40175008> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Change the behavior of "X-Frame-Options: SAMEORIGIN" to ensure that all ancestors frames >+ are same-origin with the document that delivered this header. This prevents an intermediary >+ malicious frame from clickjacking a child frame whose document is same-origin with the top- >+ level frame. It also makes the behavior of X-Frame-Options in WebKit more closely match >+ the behavior of X-Frame-Options in other browsers, including Chrome and Firefox. >+ >+ Currently a document delivered with "X-Frame-Options: SAMEORIGIN" must only be same-origin >+ with the top-level frame's document in order to be displayed. This prevents clickjacking by >+ a malicious page that embeds a page delivered with "X-Frame-Options: SAMEORIGIN". However, >+ it does not protect against clickjacking of the "X-Frame-Options: SAMEORIGIN" page (victim) >+ if embedded by an intermediate malicious iframe, say a "rogue ad", that was embedded in a >+ document same origin with the victim page. We should protect against such attacks. >+ >+ Tests: http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow.html >+ http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny.html >+ >+ * loader/FrameLoader.cpp: >+ (WebCore::FrameLoader::shouldInterruptLoadForXFrameOptions): >+ > 2018-05-11 Daniel Bates <dabates@apple.com> > > [iOS] Text decoration of dragged content does not paint with opacity >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index dfff45a14e143c2e050de3eedf16d5e06db12442..3fe76f909ab759b6ad62ef37c427af18dba0b06e 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,27 @@ >+2018-05-11 Daniel Bates <dabates@apple.com> >+ >+ X-Frame-Options: SAMEORIGIN needs to check all ancestor frames >+ https://bugs.webkit.org/show_bug.cgi?id=185567 >+ <rdar://problem/40175008> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Change the behavior of "X-Frame-Options: SAMEORIGIN" to ensure that all ancestors frames >+ are same-origin with the document that delivered this header. This prevents an intermediary >+ malicious frame from clickjacking a child frame whose document is same-origin with the top- >+ level frame. It also makes the behavior of X-Frame-Options in WebKit more closely match >+ the behavior of X-Frame-Options in other browsers, including Chrome and Firefox. >+ >+ Currently a document delivered with "X-Frame-Options: SAMEORIGIN" must only be same-origin >+ with the top-level frame's document in order to be displayed. This prevents clickjacking by >+ a malicious page that embeds a page delivered with "X-Frame-Options: SAMEORIGIN". However, >+ it does not protect against clickjacking of the "X-Frame-Options: SAMEORIGIN" page (victim) >+ if embedded by an intermediate malicious iframe, say a "rogue ad", that was embedded in a >+ document same origin with the victim page. We should protect against such attacks. >+ >+ * NetworkProcess/NetworkResourceLoader.cpp: >+ (WebKit::NetworkResourceLoader::shouldInterruptLoadForXFrameOptions): >+ > 2018-05-11 Brady Eidson <beidson@apple.com> > > Make sure history navigations reuse the existing process when necessary. >diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp >index 0a5aff2181acf02e78963ed472d4b64e6435eb61..5fefaa0757fa38822f70cb0851bf53ae364ef514 100644 >--- a/Source/WebCore/loader/FrameLoader.cpp >+++ b/Source/WebCore/loader/FrameLoader.cpp >@@ -3420,7 +3420,7 @@ bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, con > return true; > for (Frame* frame = m_frame.tree().parent(); frame; frame = frame->tree().parent()) { > if (!origin->isSameSchemeHostPort(frame->document()->securityOrigin())) >- break; >+ return true; > } > return false; > } >diff --git a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp >index 696c9af5e9ae7670bdaa93c2942e88901c0d5f12..d2e92a16872b8f6716f9f23f0b6a446f88277d93 100644 >--- a/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp >+++ b/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp >@@ -414,8 +414,16 @@ bool NetworkResourceLoader::shouldInterruptLoadForXFrameOptions(const String& xF > return false; > case XFrameOptionsDeny: > return true; >- case XFrameOptionsSameOrigin: >- return !SecurityOrigin::create(url)->isSameSchemeHostPort(*m_parameters.sourceOrigin); >+ case XFrameOptionsSameOrigin: { >+ auto origin = SecurityOrigin::create(url); >+ if (!SecurityOrigin::create(url)->isSameSchemeHostPort(*m_parameters.sourceOrigin)) >+ return true; >+ for (auto& origin : m_parameters.frameAncestorOrigins) { >+ if (!origin->isSameSchemeHostPort(*origin)) >+ return true; >+ } >+ return false; >+ } > case XFrameOptionsConflict: { > String errorMessage = "Multiple 'X-Frame-Options' headers with conflicting values ('" + xFrameOptions + "') encountered when loading '" + url.stringCenterEllipsizedToLength() + "'. Falling back to 'DENY'."; > send(Messages::WebPage::AddConsoleMessage { m_parameters.webFrameID, MessageSource::JS, MessageLevel::Error, errorMessage, identifier() }, m_parameters.webPageID); >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 50aaf21c7e751871ec13ec04c7c1de99c6cd47da..e29d52e57fb0023a1510176e7aa367f23935df89 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,25 @@ >+2018-05-11 Daniel Bates <dabates@apple.com> >+ >+ X-Frame-Options: SAMEORIGIN needs to check all ancestor frames >+ https://bugs.webkit.org/show_bug.cgi?id=185567 >+ <rdar://problem/40175008> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add tests to ensure that "X-Frame-Options: SAMEORIGIN" checks ancestor frames. >+ >+ * http/tests/cookies/same-site/fetch-after-navigating-iframe-in-cross-origin-page.html: >+ * http/tests/cookies/same-site/fetch-after-top-level-navigation-initiated-from-iframe-in-cross-origin-page.html: >+ * http/tests/cookies/same-site/fetch-in-cross-origin-iframe.html: >+ * http/tests/resources/echo-iframe-src.php: Copied from LayoutTests/http/tests/cookies/same-site/resources/echo-iframe-src.php. >+ * http/tests/security/XFrameOptions/resources/x-frame-options-ancestors-same-origin-deny.html: Added. >+ * http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-allow.cgi: Added. >+ * http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-deny.cgi: Added. >+ * http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow-expected.txt: Added. >+ * http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow.html: Added. >+ * http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny-expected.txt: Added. >+ * http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny.html: Renamed from LayoutTests/http/tests/cookies/same-site/resources/echo-iframe-src.php. >+ > 2018-05-11 Youenn Fablet <youenn@apple.com> > > Layout Test webrtc/addICECandidate-closed.html is a flaky failure >diff --git a/LayoutTests/http/tests/cookies/same-site/fetch-after-navigating-iframe-in-cross-origin-page.html b/LayoutTests/http/tests/cookies/same-site/fetch-after-navigating-iframe-in-cross-origin-page.html >index cb2e52021cff1f57322383c9015fdd4fdc3f4169..b902fb24bcc022601316620c8b76e1a8b3908d66 100644 >--- a/LayoutTests/http/tests/cookies/same-site/fetch-after-navigating-iframe-in-cross-origin-page.html >+++ b/LayoutTests/http/tests/cookies/same-site/fetch-after-navigating-iframe-in-cross-origin-page.html >@@ -11,7 +11,7 @@ async function runTest() > await setCookie("implicit-strict", "6", {"SameSite": null, "Max-Age": 100, "path": "/"}); > await setCookie("strict-because-invalid-SameSite-value", "6", {"SameSite": "invalid", "Max-Age": 100, "path": "/"}); > await setCookie("lax", "6", {"SameSite": "Lax", "Max-Age": 100, "path": "/"}); >- window.location.href = "http://localhost:8000/cookies/same-site/resources/echo-iframe-src.php?src=http%3A//127.0.0.1%3A8000/cookies/same-site/resources/click-hyperlink.php%3Fhref%3Dfetch-after-navigating-iframe-in-cross-origin-page.php"; >+ window.location.href = "http://localhost:8000/resources/echo-iframe-src.php?src=http%3A//127.0.0.1%3A8000/cookies/same-site/resources/click-hyperlink.php%3Fhref%3Dfetch-after-navigating-iframe-in-cross-origin-page.php"; > } > runTest(); > </script> >diff --git a/LayoutTests/http/tests/cookies/same-site/fetch-after-top-level-navigation-initiated-from-iframe-in-cross-origin-page.html b/LayoutTests/http/tests/cookies/same-site/fetch-after-top-level-navigation-initiated-from-iframe-in-cross-origin-page.html >index 66143b8484d660ce19ebdaee57d1e6a881d81a42..824925e9272a84e3c8d75c752dbe67a64b2d65e9 100644 >--- a/LayoutTests/http/tests/cookies/same-site/fetch-after-top-level-navigation-initiated-from-iframe-in-cross-origin-page.html >+++ b/LayoutTests/http/tests/cookies/same-site/fetch-after-top-level-navigation-initiated-from-iframe-in-cross-origin-page.html >@@ -11,7 +11,7 @@ async function runTest() > await setCookie("implicit-strict", "4", {"SameSite": null, "Max-Age": 100, "path": "/"}); > await setCookie("strict-because-invalid-SameSite-value", "4", {"SameSite": "invalid", "Max-Age": 100, "path": "/"}); > await setCookie("lax", "4", {"SameSite": "Lax", "Max-Age": 100, "path": "/"}); >- window.location.href = "http://localhost:8000/cookies/same-site/resources/echo-iframe-src.php?src=http%3A//127.0.0.1%3A8000/cookies/same-site/resources/click-hyperlink.php%3Fhref%3Dfetch-after-top-level-navigation-initiated-from-iframe-in-cross-origin-page.php%26target%3D_top"; >+ window.location.href = "http://localhost:8000/resources/echo-iframe-src.php?src=http%3A//127.0.0.1%3A8000/cookies/same-site/resources/click-hyperlink.php%3Fhref%3Dfetch-after-top-level-navigation-initiated-from-iframe-in-cross-origin-page.php%26target%3D_top"; > } > runTest(); > </script> >diff --git a/LayoutTests/http/tests/cookies/same-site/fetch-in-cross-origin-iframe.html b/LayoutTests/http/tests/cookies/same-site/fetch-in-cross-origin-iframe.html >index 8dc9aa6b9d739f0d9afd5f272c15d35e0c21b6b7..8a1c6902b1410ed1925e5ee36d346903d9907113 100644 >--- a/LayoutTests/http/tests/cookies/same-site/fetch-in-cross-origin-iframe.html >+++ b/LayoutTests/http/tests/cookies/same-site/fetch-in-cross-origin-iframe.html >@@ -11,7 +11,7 @@ async function runTest() > await setCookie("implicit-strict", "3", {"SameSite": null, "Max-Age": 100, "path": "/"}); > await setCookie("strict-because-invalid-SameSite-value", "3", {"SameSite": "invalid", "Max-Age": 100, "path": "/"}); > await setCookie("lax", "3", {"SameSite": "Lax", "Max-Age": 100, "path": "/"}); >- window.location.href = "http://127.0.0.1:8000/cookies/same-site/resources/echo-iframe-src.php?src=http://localhost:8000/cookies/same-site/resources/fetch-in-cross-origin-iframe.html"; >+ window.location.href = "http://127.0.0.1:8000/resources/echo-iframe-src.php?src=http://localhost:8000/cookies/same-site/resources/fetch-in-cross-origin-iframe.html"; > } > runTest(); > </script> >diff --git a/LayoutTests/http/tests/cookies/same-site/resources/echo-iframe-src.php b/LayoutTests/http/tests/cookies/same-site/resources/echo-iframe-src.php >deleted file mode 100644 >index b37bd78af869d4f0ecdb0ef2153cf031131ac620..0000000000000000000000000000000000000000 >--- a/LayoutTests/http/tests/cookies/same-site/resources/echo-iframe-src.php >+++ /dev/null >@@ -1,15 +0,0 @@ >-<!DOCTYPE html> >-<html> >-<head> >-<script> >-if (window.testRunner) { >- testRunner.dumpAsText(); >- testRunner.dumpChildFramesAsText(); >- testRunner.waitUntilDone(); >-} >-</script> >-</head> >-<body> >-<iframe src="<?php echo $_GET['src']; ?>"></iframe> >-</body> >-</html> >diff --git a/LayoutTests/http/tests/resources/echo-iframe-src.php b/LayoutTests/http/tests/resources/echo-iframe-src.php >new file mode 100644 >index 0000000000000000000000000000000000000000..b37bd78af869d4f0ecdb0ef2153cf031131ac620 >--- /dev/null >+++ b/LayoutTests/http/tests/resources/echo-iframe-src.php >@@ -0,0 +1,15 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script> >+if (window.testRunner) { >+ testRunner.dumpAsText(); >+ testRunner.dumpChildFramesAsText(); >+ testRunner.waitUntilDone(); >+} >+</script> >+</head> >+<body> >+<iframe src="<?php echo $_GET['src']; ?>"></iframe> >+</body> >+</html> >diff --git a/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-ancestors-same-origin-deny.html b/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-ancestors-same-origin-deny.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ea7fc44a9fa1602a2f3995c2b4a7cdf478b3f4df >--- /dev/null >+++ b/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-ancestors-same-origin-deny.html >@@ -0,0 +1,24 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script> >+function checkIfDone() { >+ try { >+ var url = document.querySelector("iframe").contentWindow.location.href; >+ if (url) >+ console.log("FAIL: Could read contentWindow.location.href"); >+ else >+ throw null; >+ } catch (e) { >+ if (e) >+ console.log(e); >+ console.log("PASS: Could not read contentWindow.location.href"); >+ } >+ testRunner.notifyDone(); >+} >+</script> >+</head> >+<body> >+<iframe src="http://127.0.0.1:8000/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-deny.cgi" onload="checkIfDone()"></iframe> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-allow.cgi b/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-allow.cgi >new file mode 100755 >index 0000000000000000000000000000000000000000..c202015e567899a6151d2f5c3998a575a1c35986 >--- /dev/null >+++ b/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-allow.cgi >@@ -0,0 +1,14 @@ >+#!/usr/bin/perl -wT >+use strict; >+ >+print "Content-Type: text/html\n"; >+print "Cache-Control: no-cache, no-store\n"; >+print "X-FRAME-OPTIONS: sameorigin\n\n"; >+ >+print <<"EOF"; >+<p>PASS: This should show up as all frame ancestors are same origin with this page.</p> >+<script> >+if (window.testRunner) >+ testRunner.notifyDone(); >+</script> >+EOF >diff --git a/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-deny.cgi b/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-deny.cgi >new file mode 100755 >index 0000000000000000000000000000000000000000..2b097005f6aa50252ae1207a5f6b5b3e86dbd4ba >--- /dev/null >+++ b/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-deny.cgi >@@ -0,0 +1,8 @@ >+#!/usr/bin/perl -wT >+use strict; >+ >+print "Content-Type: text/html\n"; >+print "Cache-Control: no-cache, no-store\n"; >+print "X-FRAME-OPTIONS: sameorigin\n\n"; >+ >+print "<p>FAIL: This should not show up as one or more frame ancestors are not same origin with this page.</p>\n"; >diff --git a/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow-expected.txt b/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..4a59226364217589272a36dc6f04e464b7e2b0da >--- /dev/null >+++ b/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow-expected.txt >@@ -0,0 +1,11 @@ >+ >+ >+-------- >+Frame: '<!--frame1-->' >+-------- >+ >+ >+-------- >+Frame: '<!--frame2-->' >+-------- >+PASS: This should show up as all frame ancestors are same origin with this page. >diff --git a/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow.html b/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow.html >new file mode 100644 >index 0000000000000000000000000000000000000000..528dfd91117dda2538affa658dec31a662cd37a6 >--- /dev/null >+++ b/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow.html >@@ -0,0 +1,15 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script> >+if (window.testRunner) { >+ testRunner.dumpAsText(); >+ testRunner.dumpChildFramesAsText(); >+ testRunner.waitUntilDone(); >+} >+</script> >+</head> >+<head> >+<iframe src="http://127.0.0.1:8000/resources/echo-iframe-src.php?src=http%3A//127.0.0.1%3A8000/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-allow.cgi"></iframe> >+</head> >+</html> >diff --git a/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny-expected.txt b/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d58ace4b428b8a095e976186192847f9768eebda >--- /dev/null >+++ b/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny-expected.txt >@@ -0,0 +1,14 @@ >+CONSOLE MESSAGE: Refused to display 'http://127.0.0.1:8000/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-deny.cgi' in a frame because it set 'X-Frame-Options' to 'sameorigin'. >+CONSOLE MESSAGE: line 14: SecurityError: Sandbox access violation: Blocked a frame at "http://localhost:8000" from accessing a cross-origin frame. The frame being accessed is sandboxed and lacks the "allow-same-origin" flag. >+CONSOLE MESSAGE: line 15: PASS: Could not read contentWindow.location.href >+ >+ >+-------- >+Frame: '<!--frame1-->' >+-------- >+ >+ >+-------- >+Frame: '<!--frame2-->' >+-------- >+ >diff --git a/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny.html b/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0e5095cde8f95aef8c838032296dece2e7340045 >--- /dev/null >+++ b/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny.html >@@ -0,0 +1,15 @@ >+<!DOCTYPE html> >+<html> >+<head> >+<script> >+if (window.testRunner) { >+ testRunner.dumpAsText(); >+ testRunner.dumpChildFramesAsText(); >+ testRunner.waitUntilDone(); >+} >+</script> >+</head> >+<head> >+<iframe src="http://localhost:8000/security/XFrameOptions/resources/x-frame-options-ancestors-same-origin-deny.html"></iframe> >+</head> >+</html>
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
Flags:
bfulgham
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185567
:
340230
|
340239