Diff
Modified: trunk/LayoutTests/ChangeLog (231729 => 231730)
--- trunk/LayoutTests/ChangeLog 2018-05-12 02:11:05 UTC (rev 231729)
+++ trunk/LayoutTests/ChangeLog 2018-05-12 04:11:16 UTC (rev 231730)
@@ -1,3 +1,25 @@
+2018-05-11 Daniel Bates <[email protected]>
+
+ X-Frame-Options: SAMEORIGIN needs to check all ancestor frames
+ https://bugs.webkit.org/show_bug.cgi?id=185567
+ <rdar://problem/40175008>
+
+ Reviewed by Brent Fulgham.
+
+ 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 Nan Wang <[email protected]>
AX: In role=dialog elements with aria-modal=true VoiceOver iOS/macOS can't manually focus or read dialog paragraph description text inside the modal.
Modified: trunk/LayoutTests/http/tests/cookies/same-site/fetch-after-navigating-iframe-in-cross-origin-page.html (231729 => 231730)
--- trunk/LayoutTests/http/tests/cookies/same-site/fetch-after-navigating-iframe-in-cross-origin-page.html 2018-05-12 02:11:05 UTC (rev 231729)
+++ trunk/LayoutTests/http/tests/cookies/same-site/fetch-after-navigating-iframe-in-cross-origin-page.html 2018-05-12 04:11:16 UTC (rev 231730)
@@ -11,7 +11,7 @@
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 = ""
+ window.location.href = ""
}
runTest();
</script>
Modified: trunk/LayoutTests/http/tests/cookies/same-site/fetch-after-top-level-navigation-initiated-from-iframe-in-cross-origin-page.html (231729 => 231730)
--- trunk/LayoutTests/http/tests/cookies/same-site/fetch-after-top-level-navigation-initiated-from-iframe-in-cross-origin-page.html 2018-05-12 02:11:05 UTC (rev 231729)
+++ trunk/LayoutTests/http/tests/cookies/same-site/fetch-after-top-level-navigation-initiated-from-iframe-in-cross-origin-page.html 2018-05-12 04:11:16 UTC (rev 231730)
@@ -11,7 +11,7 @@
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 = ""
+ window.location.href = ""
}
runTest();
</script>
Modified: trunk/LayoutTests/http/tests/cookies/same-site/fetch-in-cross-origin-iframe.html (231729 => 231730)
--- trunk/LayoutTests/http/tests/cookies/same-site/fetch-in-cross-origin-iframe.html 2018-05-12 02:11:05 UTC (rev 231729)
+++ trunk/LayoutTests/http/tests/cookies/same-site/fetch-in-cross-origin-iframe.html 2018-05-12 04:11:16 UTC (rev 231730)
@@ -11,7 +11,7 @@
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 = ""
+ window.location.href = ""
}
runTest();
</script>
Deleted: trunk/LayoutTests/http/tests/cookies/same-site/resources/echo-iframe-src.php (231729 => 231730)
--- trunk/LayoutTests/http/tests/cookies/same-site/resources/echo-iframe-src.php 2018-05-12 02:11:05 UTC (rev 231729)
+++ trunk/LayoutTests/http/tests/cookies/same-site/resources/echo-iframe-src.php 2018-05-12 04:11:16 UTC (rev 231730)
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script>
-if (window.testRunner) {
- testRunner.dumpAsText();
- testRunner.dumpChildFramesAsText();
- testRunner.waitUntilDone();
-}
-</script>
-</head>
-<body>
-<iframe src="" echo $_GET['src']; ?>"></iframe>
-</body>
-</html>
Added: trunk/LayoutTests/http/tests/resources/echo-iframe-src.php (0 => 231730)
--- trunk/LayoutTests/http/tests/resources/echo-iframe-src.php (rev 0)
+++ trunk/LayoutTests/http/tests/resources/echo-iframe-src.php 2018-05-12 04:11:16 UTC (rev 231730)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.dumpChildFramesAsText();
+ testRunner.waitUntilDone();
+}
+</script>
+</head>
+<body>
+<iframe src="" echo $_GET['src']; ?>"></iframe>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-ancestors-same-origin-deny.html (0 => 231730)
--- trunk/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-ancestors-same-origin-deny.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-ancestors-same-origin-deny.html 2018-05-12 04:11:16 UTC (rev 231730)
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+function checkIfDone() {
+ try {
+ var url = ""
+ 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="" _onload_="checkIfDone()"></iframe>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-allow.cgi (0 => 231730)
--- trunk/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-allow.cgi (rev 0)
+++ trunk/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-allow.cgi 2018-05-12 04:11:16 UTC (rev 231730)
@@ -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
Property changes on: trunk/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-allow.cgi
___________________________________________________________________
Added: svn:executable
+*
\ No newline at end of property
Added: trunk/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-deny.cgi (0 => 231730)
--- trunk/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-deny.cgi (rev 0)
+++ trunk/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-deny.cgi 2018-05-12 04:11:16 UTC (rev 231730)
@@ -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";
Property changes on: trunk/LayoutTests/http/tests/security/XFrameOptions/resources/x-frame-options-frame-ancestors-same-origin-deny.cgi
___________________________________________________________________
Added: svn:executable
+*
\ No newline at end of property
Added: trunk/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow-expected.txt (0 => 231730)
--- trunk/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow-expected.txt 2018-05-12 04:11:16 UTC (rev 231730)
@@ -0,0 +1,11 @@
+
+
+--------
+Frame: '<!--frame1-->'
+--------
+
+
+--------
+Frame: '<!--frame2-->'
+--------
+PASS: This should show up as all frame ancestors are same origin with this page.
Added: trunk/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow.html (0 => 231730)
--- trunk/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-allow.html 2018-05-12 04:11:16 UTC (rev 231730)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.dumpChildFramesAsText();
+ testRunner.waitUntilDone();
+}
+</script>
+</head>
+<head>
+<iframe src=""
+</head>
+</html>
Added: trunk/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny-expected.txt (0 => 231730)
--- trunk/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny-expected.txt 2018-05-12 04:11:16 UTC (rev 231730)
@@ -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-->'
+--------
+
Added: trunk/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny.html (0 => 231730)
--- trunk/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/XFrameOptions/x-frame-options-ancestors-same-origin-deny.html 2018-05-12 04:11:16 UTC (rev 231730)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.dumpChildFramesAsText();
+ testRunner.waitUntilDone();
+}
+</script>
+</head>
+<head>
+<iframe src=""
+</head>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (231729 => 231730)
--- trunk/Source/WebCore/ChangeLog 2018-05-12 02:11:05 UTC (rev 231729)
+++ trunk/Source/WebCore/ChangeLog 2018-05-12 04:11:16 UTC (rev 231730)
@@ -1,5 +1,32 @@
2018-05-11 Daniel Bates <[email protected]>
+ X-Frame-Options: SAMEORIGIN needs to check all ancestor frames
+ https://bugs.webkit.org/show_bug.cgi?id=185567
+ <rdar://problem/40175008>
+
+ Reviewed by Brent Fulgham.
+
+ 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 <[email protected]>
+
[iOS] Text decoration of dragged content does not paint with opacity
https://bugs.webkit.org/show_bug.cgi?id=185551
<rdar://problem/40166867>
Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (231729 => 231730)
--- trunk/Source/WebCore/loader/FrameLoader.cpp 2018-05-12 02:11:05 UTC (rev 231729)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp 2018-05-12 04:11:16 UTC (rev 231730)
@@ -3420,7 +3420,7 @@
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;
}
Modified: trunk/Source/WebKit/ChangeLog (231729 => 231730)
--- trunk/Source/WebKit/ChangeLog 2018-05-12 02:11:05 UTC (rev 231729)
+++ trunk/Source/WebKit/ChangeLog 2018-05-12 04:11:16 UTC (rev 231730)
@@ -1,3 +1,27 @@
+2018-05-11 Daniel Bates <[email protected]>
+
+ X-Frame-Options: SAMEORIGIN needs to check all ancestor frames
+ https://bugs.webkit.org/show_bug.cgi?id=185567
+ <rdar://problem/40175008>
+
+ Reviewed by Brent Fulgham.
+
+ 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 Dean Jackson <[email protected]>
WKWebViewContentProvider should know what MIME type it was created to handle
Modified: trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp (231729 => 231730)
--- trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2018-05-12 02:11:05 UTC (rev 231729)
+++ trunk/Source/WebKit/NetworkProcess/NetworkResourceLoader.cpp 2018-05-12 04:11:16 UTC (rev 231730)
@@ -414,8 +414,16 @@
return false;
case XFrameOptionsDeny:
return true;
- case XFrameOptionsSameOrigin:
- return !SecurityOrigin::create(url)->isSameSchemeHostPort(*m_parameters.sourceOrigin);
+ case XFrameOptionsSameOrigin: {
+ auto origin = SecurityOrigin::create(url);
+ if (!origin->isSameSchemeHostPort(*m_parameters.sourceOrigin))
+ return true;
+ for (auto& ancestorOrigin : m_parameters.frameAncestorOrigins) {
+ if (!origin->isSameSchemeHostPort(*ancestorOrigin))
+ 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);