diff options
Diffstat (limited to 'dom')
-rw-r--r-- | dom/base/nsDocument.cpp | 10 | ||||
-rw-r--r-- | dom/base/nsDocument.h | 1 | ||||
-rw-r--r-- | dom/interfaces/security/nsIContentSecurityPolicy.idl | 5 | ||||
-rw-r--r-- | dom/locales/en-US/chrome/security/csp.properties | 4 | ||||
-rw-r--r-- | dom/security/nsCSPContext.cpp | 14 | ||||
-rw-r--r-- | dom/security/test/csp/file_ignore_xfo.html | 10 | ||||
-rw-r--r-- | dom/security/test/csp/file_ignore_xfo.html^headers^ | 3 | ||||
-rw-r--r-- | dom/security/test/csp/file_ro_ignore_xfo.html | 10 | ||||
-rw-r--r-- | dom/security/test/csp/file_ro_ignore_xfo.html^headers^ | 3 | ||||
-rw-r--r-- | dom/security/test/csp/mochitest.ini | 5 | ||||
-rw-r--r-- | dom/security/test/csp/test_ignore_xfo.html | 59 |
11 files changed, 123 insertions, 1 deletions
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 8e6920a0e..4926b6c0a 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -61,6 +61,7 @@ #include "nsGenericHTMLElement.h" #include "mozilla/dom/CDATASection.h" #include "mozilla/dom/ProcessingInstruction.h" +#include "nsDSURIContentListener.h" #include "nsDOMString.h" #include "nsNodeUtils.h" #include "nsLayoutUtils.h" // for GetFrameForPoint @@ -2456,6 +2457,15 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel, NS_ENSURE_SUCCESS(rv, rv); } + // XFO needs to be checked after CSP because it is ignored if + // the CSP defines frame-ancestors. + if (!nsDSURIContentListener::CheckFrameOptions(aChannel, docShell, NodePrincipal())) { + MOZ_LOG(gCspPRLog, LogLevel::Debug, + ("XFO doesn't like frame's ancestry, not loading.")); + // stop! ERROR page! + aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION); + } + return NS_OK; } diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h index 17d936055..fc6749c9f 100644 --- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -1491,7 +1491,6 @@ private: void PostUnblockOnloadEvent(); void DoUnblockOnload(); - nsresult CheckFrameOptions(); nsresult InitCSP(nsIChannel* aChannel); /** diff --git a/dom/interfaces/security/nsIContentSecurityPolicy.idl b/dom/interfaces/security/nsIContentSecurityPolicy.idl index ade5b1243..51ca46f2a 100644 --- a/dom/interfaces/security/nsIContentSecurityPolicy.idl +++ b/dom/interfaces/security/nsIContentSecurityPolicy.idl @@ -98,6 +98,11 @@ interface nsIContentSecurityPolicy : nsISerializable readonly attribute bool blockAllMixedContent; /** + * Returns whether this policy enforces the frame-ancestors directive. + */ + readonly attribute bool enforcesFrameAncestors; + + /** * Obtains the referrer policy (as integer) for this browsing context as * specified in CSP. If there are multiple policies and... * - only one sets a referrer policy: that policy is returned diff --git a/dom/locales/en-US/chrome/security/csp.properties b/dom/locales/en-US/chrome/security/csp.properties index fc7fc04ba..4124ef8aa 100644 --- a/dom/locales/en-US/chrome/security/csp.properties +++ b/dom/locales/en-US/chrome/security/csp.properties @@ -91,6 +91,10 @@ ignoringReportOnlyDirective = Ignoring sandbox directive when delivered in a rep # LOCALIZATION NOTE (deprecatedReferrerDirective): # %1$S is the value of the deprecated Referrer Directive. deprecatedReferrerDirective = Referrer Directive ‘%1$S’ has been deprecated. Please use the Referrer-Policy header instead. +# LOCALIZATION NOTE (IgnoringSrcBecauseOfDirective): +# %1$S is the name of the src that is ignored. +# %2$S is the name of the directive that causes the src to be ignored. +IgnoringSrcBecauseOfDirective=Ignoring ‘%1$S’ because of ‘%2$S’ directive. # CSP Errors: # LOCALIZATION NOTE (couldntParseInvalidSource): diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp index 815c7734d..0a3e20305 100644 --- a/dom/security/nsCSPContext.cpp +++ b/dom/security/nsCSPContext.cpp @@ -343,6 +343,20 @@ nsCSPContext::GetBlockAllMixedContent(bool *outBlockAllMixedContent) } NS_IMETHODIMP +nsCSPContext::GetEnforcesFrameAncestors(bool *outEnforcesFrameAncestors) +{ + *outEnforcesFrameAncestors = false; + for (uint32_t i = 0; i < mPolicies.Length(); i++) { + if (!mPolicies[i]->getReportOnlyFlag() && + mPolicies[i]->hasDirective(nsIContentSecurityPolicy::FRAME_ANCESTORS_DIRECTIVE)) { + *outEnforcesFrameAncestors = true; + return NS_OK; + } + } + return NS_OK; +} + +NS_IMETHODIMP nsCSPContext::GetReferrerPolicy(uint32_t* outPolicy, bool* outIsSet) { *outIsSet = false; diff --git a/dom/security/test/csp/file_ignore_xfo.html b/dom/security/test/csp/file_ignore_xfo.html new file mode 100644 index 000000000..6746a3adb --- /dev/null +++ b/dom/security/test/csp/file_ignore_xfo.html @@ -0,0 +1,10 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Bug 1024557: Ignore x-frame-options if CSP with frame-ancestors exists</title> +</head> +<body> +<div id="cspmessage">Ignoring XFO because of CSP</div> +</body> +</html> diff --git a/dom/security/test/csp/file_ignore_xfo.html^headers^ b/dom/security/test/csp/file_ignore_xfo.html^headers^ new file mode 100644 index 000000000..e93f9e3ec --- /dev/null +++ b/dom/security/test/csp/file_ignore_xfo.html^headers^ @@ -0,0 +1,3 @@ +Content-Security-Policy: frame-ancestors http://mochi.test:8888 +X-Frame-Options: deny +Cache-Control: no-cache diff --git a/dom/security/test/csp/file_ro_ignore_xfo.html b/dom/security/test/csp/file_ro_ignore_xfo.html new file mode 100644 index 000000000..85e7f0092 --- /dev/null +++ b/dom/security/test/csp/file_ro_ignore_xfo.html @@ -0,0 +1,10 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Bug 1024557: Ignore x-frame-options if CSP with frame-ancestors exists</title> +</head> +<body> +<div id="cspmessage">Ignoring XFO because of CSP_RO</div> +</body> +</html>
\ No newline at end of file diff --git a/dom/security/test/csp/file_ro_ignore_xfo.html^headers^ b/dom/security/test/csp/file_ro_ignore_xfo.html^headers^ new file mode 100644 index 000000000..ab8366f06 --- /dev/null +++ b/dom/security/test/csp/file_ro_ignore_xfo.html^headers^ @@ -0,0 +1,3 @@ +Content-Security-Policy-Report-Only: frame-ancestors http://mochi.test:8888 +X-Frame-Options: deny +Cache-Control: no-cache diff --git a/dom/security/test/csp/mochitest.ini b/dom/security/test/csp/mochitest.ini index 8add999c3..535109752 100644 --- a/dom/security/test/csp/mochitest.ini +++ b/dom/security/test/csp/mochitest.ini @@ -206,6 +206,10 @@ support-files = file_iframe_srcdoc.sjs file_iframe_sandbox_srcdoc.html file_iframe_sandbox_srcdoc.html^headers^ + file_ignore_xfo.html + file_ignore_xfo.html^headers^ + file_ro_ignore_xfo.html + file_ro_ignore_xfo.html^headers^ [test_base-uri.html] [test_blob_data_schemes.html] @@ -298,3 +302,4 @@ tags = mcb support-files = file_sandbox_allow_scripts.html file_sandbox_allow_scripts.html^headers^ +[test_ignore_xfo.html] diff --git a/dom/security/test/csp/test_ignore_xfo.html b/dom/security/test/csp/test_ignore_xfo.html new file mode 100644 index 000000000..fb3aadc6c --- /dev/null +++ b/dom/security/test/csp/test_ignore_xfo.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 1024557: Ignore x-frame-options if CSP with frame-ancestors exists</title> + <!-- Including SimpleTest.js so we can use waitForExplicitFinish !--> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<iframe style="width:100%;" id="csp_testframe"></iframe> +<iframe style="width:100%;" id="csp_ro_testframe"></iframe> + +<script class="testbody" type="text/javascript"> + +/* + * We load two frames using: + * x-frame-options: deny + * where the first frame uses a csp and the second a csp_ro including frame-ancestors. + * We make sure that xfo is ignored for regular csp but not for csp_ro. + */ + +SimpleTest.waitForExplicitFinish(); + +var testcounter = 0; +function checkFinished() { + testcounter++; + if (testcounter < 2) { + return; + } + SimpleTest.finish(); +} + +// 1) test XFO with CSP +var csp_testframe = document.getElementById("csp_testframe"); +csp_testframe.onload = function() { + var msg = csp_testframe.contentWindow.document.getElementById("cspmessage"); + is(msg.innerHTML, "Ignoring XFO because of CSP", "Loading frame with with XFO and CSP"); + checkFinished(); +} +csp_testframe.onerror = function() { + ok(false, "sanity: should not fire onerror for csp_testframe"); +} +csp_testframe.src = "file_ignore_xfo.html"; + +// 2) test XFO with CSP_RO +var csp_ro_testframe = document.getElementById("csp_ro_testframe"); +csp_ro_testframe.onload = function() { + var msg = csp_ro_testframe.contentWindow.document.getElementById("cspmessage"); + is(msg, null, "Blocking frame with with XFO and CSP_RO"); + checkFinished(); +} +csp_ro_testframe.onerror = function() { + ok(false, "sanity: should not fire onerror for csp_ro_testframe"); +} +csp_ro_testframe.src = "file_ro_ignore_xfo.html"; + +</script> +</body> +</html> |