Bug 1599131: Remove carve outs for downloads within x-frame-options when fission enabled. r=smaug,mattwoodrow

Differential Revision: https://phabricator.services.mozilla.com/D65949

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Christoph Kerschbaumer 2020-03-13 14:20:20 +00:00
parent 8753fc5a42
commit 5ea63e55c7
16 changed files with 148 additions and 393 deletions

View File

@ -112,7 +112,6 @@
#include "mozilla/dom/Event.h"
#include "mozilla/dom/FeaturePolicy.h"
#include "mozilla/dom/FeaturePolicyUtils.h"
#include "mozilla/dom/FramingChecker.h"
#include "mozilla/dom/HTMLAllCollection.h"
#include "mozilla/dom/HTMLMetaElement.h"
#include "mozilla/dom/HTMLSharedElement.h"
@ -3170,58 +3169,6 @@ nsresult Document::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
rv = InitCSP(aChannel);
NS_ENSURE_SUCCESS(rv, rv);
// Bug 1574372: Download should be fully done in the parent process.
// Unfortunately we currently can not determine whether a load will
// result in a download in the parent process. Hence, if running in
// non-fission-mode then we will have to enforce checks for
// frame-ancestors and x-frame-options here in the content process
// but if we run in fission-mode then we do those two security
// checks within DOMSecurityManager::Observe in the parent.
bool fissionEnabled =
docShell && nsDocShell::Cast(docShell)->UseRemoteSubframes();
if (!fissionEnabled) {
nsContentPolicyType contentType = loadInfo->GetExternalContentPolicyType();
// frame-ancestor check only makes sense for subdocument and object loads,
// if this is not a load of such type, there is nothing to do here.
if (contentType == nsIContentPolicy::TYPE_SUBDOCUMENT ||
contentType == nsIContentPolicy::TYPE_OBJECT) {
// we only enforce frame-ancestors if the load is an actual http
// channel, otherwise we block dynamic iframes since about:blank
// inherits the CSP.
nsCOMPtr<nsIHttpChannel> httpChannel;
nsContentSecurityUtils::GetHttpChannelFromPotentialMultiPart(
aChannel, getter_AddRefs(httpChannel));
if (httpChannel && mCSP) {
bool safeAncestry = false;
// PermitsAncestry sends violation reports when necessary
rv = mCSP->PermitsAncestry(loadInfo, &safeAncestry);
if (NS_FAILED(rv) || !safeAncestry) {
// stop! ERROR page!
aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
}
}
}
// the checks for type_subdoc or type_object happen within
// CheckFrameOptions.
if (!FramingChecker::CheckFrameOptions(aChannel, mCSP)) {
// stop! ERROR page!
// But before we have to reset the principal of the document
// because the onload() event fires before the error page
// is displayed and we do not want the enclosing document
// to access the contentDocument.
RefPtr<NullPrincipal> nullPrincipal =
NullPrincipal::CreateWithInheritedAttributes(NodePrincipal());
// Before calling SetPrincipals() we should ensure that mFontFaceSet
// and also GetInnerWindow() is still null at this point, before
// we can fix Bug 1614735: Evaluate calls to SetPrincipal
// within Document.cpp
MOZ_ASSERT(!mFontFaceSet && !GetInnerWindow());
SetPrincipals(nullPrincipal, nullPrincipal);
aChannel->Cancel(NS_ERROR_XFO_VIOLATION);
}
}
// Initialize FeaturePolicy
rv = InitFeaturePolicy(aChannel);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -67,15 +67,10 @@ add_task(async function test() {
SpecialPowers.registerObservers("xfo-on-violate-policy");
function examiner() {
// Depending on whether xfo checks are performed in the parent
// or in the content process we have to use the specialpowers version
// for observing XFO violations. After Bug 1574372 we should be able
// to remove the "xfo-on-violate-policy" here.
SpecialPowers.addObserver(
this,
"specialpowers-xfo-on-violate-policy"
);
SpecialPowers.addObserver(this, "xfo-on-violate-policy");
}
examiner.prototype = {
observe(subject, topic, data) {
@ -92,7 +87,6 @@ add_task(async function test() {
this,
"specialpowers-xfo-on-violate-policy"
);
SpecialPowers.removeObserver(this, "xfo-on-violate-policy");
},
};
let myExaminer = new examiner();

View File

@ -1,213 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DOMSecurityManager.h"
#include "nsCSPContext.h"
#include "nsContentSecurityUtils.h"
#include "mozilla/dom/FramingChecker.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/StaticPrefs_fission.h"
#include "nsIMultiPartChannel.h"
#include "nsIObserverService.h"
#include "nsIHttpProtocolHandler.h"
using namespace mozilla;
namespace {
StaticRefPtr<DOMSecurityManager> gDOMSecurityManager;
} // namespace
NS_INTERFACE_MAP_BEGIN(DOMSecurityManager)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(DOMSecurityManager)
NS_IMPL_RELEASE(DOMSecurityManager)
/* static */
void DOMSecurityManager::Initialize() {
MOZ_ASSERT(!gDOMSecurityManager);
MOZ_ASSERT(NS_IsMainThread());
if (!XRE_IsParentProcess()) {
return;
}
RefPtr<DOMSecurityManager> service = new DOMSecurityManager();
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_WARN_IF(!obs)) {
return;
}
obs->AddObserver(service, NS_HTTP_ON_EXAMINE_RESPONSE_TOPIC, false);
obs->AddObserver(service, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
gDOMSecurityManager = std::move(service);
}
/* static */
void DOMSecurityManager::Shutdown() {
MOZ_ASSERT(NS_IsMainThread());
if (!gDOMSecurityManager) {
return;
}
RefPtr<DOMSecurityManager> service = gDOMSecurityManager.forget();
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_WARN_IF(!obs)) {
return;
}
obs->RemoveObserver(service, NS_HTTP_ON_EXAMINE_RESPONSE_TOPIC);
obs->RemoveObserver(service, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
}
NS_IMETHODIMP
DOMSecurityManager::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) {
if (!strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
Shutdown();
return NS_OK;
}
MOZ_ASSERT(!strcmp(aTopic, NS_HTTP_ON_EXAMINE_RESPONSE_TOPIC));
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aSubject);
if (NS_WARN_IF(!channel)) {
return NS_OK;
}
// Bug 1574372: Download should be fully done in the parent process.
// Unfortunately we currently can not determine whether a load will
// result in a download in the parent process. Hence, if running in
// fission-mode, then we will enforce the security checks for
// frame-ancestors and x-frame-options here in the parent using some
// additional carveouts for downloads but if we run in
// non-fission-mode then we do those two security checks within
// Document::StartDocumentLoad in the content process.
nsCOMPtr<nsILoadContext> loadContext;
NS_QueryNotificationCallbacks(channel, loadContext);
bool fissionEnabled = loadContext && loadContext->UseRemoteSubframes();
if (fissionEnabled) {
nsCOMPtr<nsIContentSecurityPolicy> csp;
nsresult rv =
ParseCSPAndEnforceFrameAncestorCheck(channel, getter_AddRefs(csp));
if (NS_FAILED(rv)) {
return rv;
}
// X-Frame-Options needs to be enforced after CSP frame-ancestors
// checks because if frame-ancestors is present, then x-frame-options
// will be discarded
EnforceXFrameOptionsCheck(channel, csp);
}
return NS_OK;
}
nsresult DOMSecurityManager::ParseCSPAndEnforceFrameAncestorCheck(
nsIChannel* aChannel, nsIContentSecurityPolicy** aOutCSP) {
MOZ_ASSERT(aChannel);
// CSP can only hang off an http channel, if this channel is not
// an http channel then there is nothing to do here.
nsCOMPtr<nsIHttpChannel> httpChannel;
nsresult rv = nsContentSecurityUtils::GetHttpChannelFromPotentialMultiPart(
aChannel, getter_AddRefs(httpChannel));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!httpChannel) {
return NS_OK;
}
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
nsContentPolicyType contentType = loadInfo->GetExternalContentPolicyType();
// frame-ancestor check only makes sense for subdocument and object loads,
// if this is not a load of such type, there is nothing to do here.
if (contentType != nsIContentPolicy::TYPE_SUBDOCUMENT &&
contentType != nsIContentPolicy::TYPE_OBJECT) {
return NS_OK;
}
nsAutoCString tCspHeaderValue, tCspROHeaderValue;
Unused << httpChannel->GetResponseHeader(
NS_LITERAL_CSTRING("content-security-policy"), tCspHeaderValue);
Unused << httpChannel->GetResponseHeader(
NS_LITERAL_CSTRING("content-security-policy-report-only"),
tCspROHeaderValue);
// if there are no CSP values, then there is nothing to do here.
if (tCspHeaderValue.IsEmpty() && tCspROHeaderValue.IsEmpty()) {
return NS_OK;
}
NS_ConvertASCIItoUTF16 cspHeaderValue(tCspHeaderValue);
NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue);
RefPtr<nsCSPContext> csp = new nsCSPContext();
nsCOMPtr<nsIPrincipal> resultPrincipal;
rv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
aChannel, getter_AddRefs(resultPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> selfURI;
aChannel->GetURI(getter_AddRefs(selfURI));
nsCOMPtr<nsIReferrerInfo> referrerInfo = httpChannel->GetReferrerInfo();
nsAutoString referrerSpec;
if (referrerInfo) {
referrerInfo->GetComputedReferrerSpec(referrerSpec);
}
uint64_t innerWindowID = loadInfo->GetInnerWindowID();
rv = csp->SetRequestContextWithPrincipal(resultPrincipal, selfURI,
referrerSpec, innerWindowID);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// ----- if there's a full-strength CSP header, apply it.
if (!cspHeaderValue.IsEmpty()) {
rv = CSP_AppendCSPFromHeader(csp, cspHeaderValue, false);
NS_ENSURE_SUCCESS(rv, rv);
}
// ----- if there's a report-only CSP header, apply it.
if (!cspROHeaderValue.IsEmpty()) {
rv = CSP_AppendCSPFromHeader(csp, cspROHeaderValue, true);
NS_ENSURE_SUCCESS(rv, rv);
}
// ----- Enforce frame-ancestor policy on any applied policies
bool safeAncestry = false;
// PermitsAncestry sends violation reports when necessary
rv = csp->PermitsAncestry(loadInfo, &safeAncestry);
if (NS_FAILED(rv) || !safeAncestry) {
// stop! ERROR page!
aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
}
// return the CSP for x-frame-options check
csp.forget(aOutCSP);
return NS_OK;
}
void DOMSecurityManager::EnforceXFrameOptionsCheck(
nsIChannel* aChannel, nsIContentSecurityPolicy* aCsp) {
MOZ_ASSERT(aChannel);
if (!FramingChecker::CheckFrameOptions(aChannel, aCsp)) {
// stop! ERROR page!
aChannel->Cancel(NS_ERROR_XFO_VIOLATION);
}
}

View File

@ -1,39 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_DOMSecurityManager_h
#define mozilla_dom_DOMSecurityManager_h
#include "nsIObserver.h"
#include "nsIContentSecurityPolicy.h"
class nsIChannel;
class DOMSecurityManager final : public nsIObserver {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
static void Initialize();
private:
DOMSecurityManager() = default;
~DOMSecurityManager() = default;
// Only enforces the frame-ancestor check which needs to happen in
// the parent because we can only access the window global in the
// parent. The actual CSP gets parsed and applied in content.
nsresult ParseCSPAndEnforceFrameAncestorCheck(
nsIChannel* aChannel, nsIContentSecurityPolicy** aOutCSP);
// XFO checks are ignored in case CSP frame-ancestors is present,
void EnforceXFrameOptionsCheck(nsIChannel* aChannel,
nsIContentSecurityPolicy* aCsp);
static void Shutdown();
};
#endif /* mozilla_dom_DOMSecurityManager_h */

View File

@ -18,6 +18,7 @@
#include "mozilla/BasePrincipal.h"
#include "mozilla/dom/nsCSPUtils.h"
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/NullPrincipal.h"
#include "nsIStringBundle.h"
@ -98,17 +99,10 @@ void FramingChecker::ReportError(const char* aMessageTag,
nsCOMPtr<nsIURI> parentURI;
if (aParentContext) {
BrowsingContext* topContext = aParentContext->Top();
// If fission is enabled, then ReportError is called in the parent
// process, otherwise in the content process. After Bug 1574372 we
// should be able to remove that branching code for querying parentURI.
if (XRE_IsParentProcess()) {
WindowGlobalParent* window =
topContext->Canonical()->GetCurrentWindowGlobal();
if (window) {
parentURI = window->GetDocumentURI();
}
} else if (nsPIDOMWindowOuter* windowOuter = topContext->GetDOMWindow()) {
parentURI = windowOuter->GetDocumentURI();
WindowGlobalParent* window =
topContext->Canonical()->GetCurrentWindowGlobal();
if (window) {
parentURI = window->GetDocumentURI();
}
ReportError(aMessageTag, parentURI, aChildURI, aPolicy, aInnerWindowID);
}
@ -138,19 +132,12 @@ bool FramingChecker::CheckOneFrameOptionsPolicy(nsIHttpChannel* aHttpChannel,
while (ctx) {
nsCOMPtr<nsIPrincipal> principal;
// If fission is enabled, then CheckOneFrameOptionsPolicy is called in the
// parent process, otherwise in the content process. After Bug 1574372 we
// should be able to remove that branching code for querying principal.
if (XRE_IsParentProcess()) {
WindowGlobalParent* window = ctx->Canonical()->GetCurrentWindowGlobal();
if (window) {
// Using the URI of the Principal and not the document because e.g.
// window.open inherits the principal and hence the URI of the
// opening context needed for same origin checks.
principal = window->DocumentPrincipal();
}
} else if (nsPIDOMWindowOuter* windowOuter = ctx->GetDOMWindow()) {
principal = nsGlobalWindowOuter::Cast(windowOuter)->GetPrincipal();
WindowGlobalParent* window = ctx->Canonical()->GetCurrentWindowGlobal();
if (window) {
// Using the URI of the Principal and not the document because e.g.
// window.open inherits the principal and hence the URI of the
// opening context needed for same origin checks.
principal = window->DocumentPrincipal();
}
if (principal && principal->IsSystemPrincipal()) {
@ -227,6 +214,8 @@ static bool ShouldIgnoreFrameOptions(nsIChannel* aChannel,
/* static */
bool FramingChecker::CheckFrameOptions(nsIChannel* aChannel,
nsIContentSecurityPolicy* aCsp) {
MOZ_ASSERT(XRE_IsParentProcess(), "check frame options only in parent");
if (!aChannel) {
return true;
}
@ -253,22 +242,6 @@ bool FramingChecker::CheckFrameOptions(nsIChannel* aChannel,
return true;
}
// Bug 1574372: Download should be fully done in the parent process.
// Unfortunately we currently can not determine whether a load will
// result in a download in the parent process. As an interim hotfix
// for Bug 1593832, we are going to allow loads using a content-type
// of 'application/octet-stream' which will definitley result in
// a download.
if (XRE_IsParentProcess()) {
// Bug 1599131: Remove carve outs for downloads within x-frame-options
// when fission enabled
nsAutoCString type;
aChannel->GetContentType(type);
if (type.LowerCaseEqualsLiteral("application/octet-stream")) {
return true;
}
}
nsCOMPtr<nsIHttpChannel> httpChannel;
nsresult rv = nsContentSecurityUtils::GetHttpChannelFromPotentialMultiPart(
aChannel, getter_AddRefs(httpChannel));

View File

@ -13,7 +13,6 @@ DIRS += [ 'featurepolicy' ]
EXPORTS.mozilla.dom += [
'CSPEvalChecker.h',
'DOMSecurityManager.h',
'DOMSecurityMonitor.h',
'FramingChecker.h',
'nsContentSecurityManager.h',
@ -38,7 +37,6 @@ EXPORTS += [
UNIFIED_SOURCES += [
'CSPEvalChecker.cpp',
'DOMSecurityManager.cpp',
'DOMSecurityMonitor.cpp',
'FramingChecker.cpp',
'nsContentSecurityManager.cpp',

View File

@ -1529,6 +1529,7 @@ nsresult nsCSPContext::AsyncReportViolation(
NS_IMETHODIMP
nsCSPContext::PermitsAncestry(nsILoadInfo* aLoadInfo,
bool* outPermitsAncestry) {
MOZ_ASSERT(XRE_IsParentProcess(), "frame-ancestor check only in parent");
nsresult rv;
*outPermitsAncestry = true;
@ -1542,16 +1543,9 @@ nsCSPContext::PermitsAncestry(nsILoadInfo* aLoadInfo,
while (ctx) {
nsCOMPtr<nsIURI> currentURI;
// If fission is enabled, then permitsAncestry is called in the parent
// process, otherwise in the content process. After Bug 1574372 we should
// be able to remove that branching code for querying currentURI.
if (XRE_IsParentProcess()) {
WindowGlobalParent* window = ctx->Canonical()->GetCurrentWindowGlobal();
if (window) {
currentURI = window->GetDocumentURI();
}
} else if (nsPIDOMWindowOuter* windowOuter = ctx->GetDOMWindow()) {
currentURI = windowOuter->GetDocumentURI();
WindowGlobalParent* window = ctx->Canonical()->GetCurrentWindowGlobal();
if (window) {
currentURI = window->GetDocumentURI();
}
if (currentURI) {

View File

@ -606,6 +606,124 @@ nsresult nsContentSecurityUtils::GetHttpChannelFromPotentialMultiPart(
return NS_OK;
}
nsresult ParseCSPAndEnforceFrameAncestorCheck(
nsIChannel* aChannel, nsIContentSecurityPolicy** aOutCSP) {
MOZ_ASSERT(aChannel);
// CSP can only hang off an http channel, if this channel is not
// an http channel then there is nothing to do here.
nsCOMPtr<nsIHttpChannel> httpChannel;
nsresult rv = nsContentSecurityUtils::GetHttpChannelFromPotentialMultiPart(
aChannel, getter_AddRefs(httpChannel));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (!httpChannel) {
return NS_OK;
}
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
nsContentPolicyType contentType = loadInfo->GetExternalContentPolicyType();
// frame-ancestor check only makes sense for subdocument and object loads,
// if this is not a load of such type, there is nothing to do here.
if (contentType != nsIContentPolicy::TYPE_SUBDOCUMENT &&
contentType != nsIContentPolicy::TYPE_OBJECT) {
return NS_OK;
}
nsAutoCString tCspHeaderValue, tCspROHeaderValue;
Unused << httpChannel->GetResponseHeader(
NS_LITERAL_CSTRING("content-security-policy"), tCspHeaderValue);
Unused << httpChannel->GetResponseHeader(
NS_LITERAL_CSTRING("content-security-policy-report-only"),
tCspROHeaderValue);
// if there are no CSP values, then there is nothing to do here.
if (tCspHeaderValue.IsEmpty() && tCspROHeaderValue.IsEmpty()) {
return NS_OK;
}
NS_ConvertASCIItoUTF16 cspHeaderValue(tCspHeaderValue);
NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue);
RefPtr<nsCSPContext> csp = new nsCSPContext();
nsCOMPtr<nsIPrincipal> resultPrincipal;
rv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
aChannel, getter_AddRefs(resultPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> selfURI;
aChannel->GetURI(getter_AddRefs(selfURI));
nsCOMPtr<nsIReferrerInfo> referrerInfo = httpChannel->GetReferrerInfo();
nsAutoString referrerSpec;
if (referrerInfo) {
referrerInfo->GetComputedReferrerSpec(referrerSpec);
}
uint64_t innerWindowID = loadInfo->GetInnerWindowID();
rv = csp->SetRequestContextWithPrincipal(resultPrincipal, selfURI,
referrerSpec, innerWindowID);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// ----- if there's a full-strength CSP header, apply it.
if (!cspHeaderValue.IsEmpty()) {
rv = CSP_AppendCSPFromHeader(csp, cspHeaderValue, false);
NS_ENSURE_SUCCESS(rv, rv);
}
// ----- if there's a report-only CSP header, apply it.
if (!cspROHeaderValue.IsEmpty()) {
rv = CSP_AppendCSPFromHeader(csp, cspROHeaderValue, true);
NS_ENSURE_SUCCESS(rv, rv);
}
// ----- Enforce frame-ancestor policy on any applied policies
bool safeAncestry = false;
// PermitsAncestry sends violation reports when necessary
rv = csp->PermitsAncestry(loadInfo, &safeAncestry);
if (NS_FAILED(rv) || !safeAncestry) {
// stop! ERROR page!
aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
return NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION;
}
// return the CSP for x-frame-options check
csp.forget(aOutCSP);
return NS_OK;
}
void EnforceXFrameOptionsCheck(nsIChannel* aChannel,
nsIContentSecurityPolicy* aCsp) {
MOZ_ASSERT(aChannel);
if (!FramingChecker::CheckFrameOptions(aChannel, aCsp)) {
// stop! ERROR page!
aChannel->Cancel(NS_ERROR_XFO_VIOLATION);
}
}
/* static */
void nsContentSecurityUtils::PerformCSPFrameAncestorAndXFOCheck(
nsIChannel* aChannel) {
nsCOMPtr<nsIContentSecurityPolicy> csp;
nsresult rv =
ParseCSPAndEnforceFrameAncestorCheck(aChannel, getter_AddRefs(csp));
if (NS_FAILED(rv)) {
return;
}
// X-Frame-Options needs to be enforced after CSP frame-ancestors
// checks because if frame-ancestors is present, then x-frame-options
// will be discarded
EnforceXFrameOptionsCheck(aChannel, csp);
}
#if defined(DEBUG)
/* static */
void nsContentSecurityUtils::AssertAboutPageHasCSP(Document* aDocument) {

View File

@ -37,6 +37,12 @@ class nsContentSecurityUtils {
static nsresult GetHttpChannelFromPotentialMultiPart(
nsIChannel* aChannel, nsIHttpChannel** aHttpChannel);
// Helper function which performs the following framing checks
// * CSP frame-ancestors
// * x-frame-options
// If any of the two disallows framing, the channel will be cancelled.
static void PerformCSPFrameAncestorAndXFOCheck(nsIChannel* aChannel);
#if defined(DEBUG)
static void AssertAboutPageHasCSP(mozilla::dom::Document* aDocument);
#endif

View File

@ -58,12 +58,7 @@ SpecialPowers.registerObservers("csp-on-violate-policy");
// This is used to watch the blocked data bounce off CSP and allowed data
// get sent out to the wire.
function examiner() {
// Depending on whether frame-ancestor checks are performed in the parent
// or in the content process we have to use the specialpowers version
// for observing CSP violations. After Bug 1574372 we should be able
// to remove the "csp-on-violate-policy" here.
SpecialPowers.addObserver(this, "specialpowers-csp-on-violate-policy");
SpecialPowers.addObserver(this, "csp-on-violate-policy");
}
examiner.prototype = {
observe(subject, topic, data) {
@ -89,8 +84,7 @@ examiner.prototype = {
// was not an nsIURI, so it was probably a cross-origin report.
}
if (topic === "specialpowers-csp-on-violate-policy" ||
topic === "csp-on-violate-policy") {
if (topic === "specialpowers-csp-on-violate-policy") {
//these were blocked... record that they were blocked
window.frameBlocked(asciiSpec, data);
}
@ -100,7 +94,6 @@ examiner.prototype = {
// or mochitests might get borked.
remove() {
SpecialPowers.removeObserver(this, "specialpowers-csp-on-violate-policy");
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
}
}

View File

@ -29,12 +29,7 @@ SpecialPowers.registerObservers("csp-on-violate-policy");
// This is used to watch the blocked data bounce off CSP and allowed data
// get sent out to the wire.
function examiner() {
// Depending on whether frame-ancestor checks are performed in the parent
// or in the content process we have to use the specialpowers version
// for observing CSP violations. After Bug 1574372 we should be able
// to remove the "csp-on-violate-policy" here.
SpecialPowers.addObserver(this, "specialpowers-csp-on-violate-policy");
SpecialPowers.addObserver(this, "csp-on-violate-policy");
}
examiner.prototype = {
observe(subject, topic, data) {
@ -60,8 +55,7 @@ examiner.prototype = {
// was not an nsIURI, so it was probably a cross-origin report.
}
if (topic === "specialpowers-csp-on-violate-policy" ||
topic === "csp-on-violate-policy") {
if (topic === "specialpowers-csp-on-violate-policy") {
//these were blocked... record that they were blocked
window.frameBlocked(asciiSpec, data);
}
@ -71,7 +65,6 @@ examiner.prototype = {
// or mochitests might get borked.
remove() {
SpecialPowers.removeObserver(this, "specialpowers-csp-on-violate-policy");
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
}
}

View File

@ -37,12 +37,7 @@ function checkFinished() {
SpecialPowers.registerObservers("xfo-on-violate-policy");
function examiner() {
// Depending on whether xfo checks are performed in the parent
// or in the content process we have to use the specialpowers version
// for observing XFO violations. After Bug 1574372 we should be able
// to remove the "xfo-on-violate-policy" here.
SpecialPowers.addObserver(this, "specialpowers-xfo-on-violate-policy");
SpecialPowers.addObserver(this, "xfo-on-violate-policy");
}
examiner.prototype = {
observe(subject, topic, data) {
@ -55,7 +50,6 @@ examiner.prototype = {
},
remove() {
SpecialPowers.removeObserver(this, "specialpowers-xfo-on-violate-policy");
SpecialPowers.removeObserver(this, "xfo-on-violate-policy");
}
}
window.examiner = new examiner();

View File

@ -105,7 +105,6 @@
#include "DecoderDoctorLogger.h"
#include "MediaDecoder.h"
#include "mozilla/ClearSiteData.h"
#include "mozilla/dom/DOMSecurityManager.h"
#include "mozilla/EditorController.h"
#include "mozilla/Fuzzyfox.h"
#include "mozilla/HTMLEditorController.h"
@ -294,8 +293,6 @@ nsresult nsLayoutStatics::Initialize() {
ClearSiteData::Initialize();
DOMSecurityManager::Initialize();
// Reporting API.
ReportingHeader::Initialize();

View File

@ -21,6 +21,7 @@
#include "mozilla/net/RedirectChannelRegistrar.h"
#include "nsDocShell.h"
#include "nsDocShellLoadState.h"
#include "nsContentSecurityUtils.h"
#include "nsHttpChannel.h"
#include "nsISecureBrowserUI.h"
#include "nsRedirectHistoryEntry.h"
@ -956,6 +957,10 @@ DocumentLoadListener::OnStartRequest(nsIRequest* aRequest) {
return NS_ERROR_UNEXPECTED;
}
// Enforce CSP frame-ancestors and x-frame-options checks which
// might cancel the channel.
nsContentSecurityUtils::PerformCSPFrameAncestorAndXFOCheck(mChannel);
// Once we initiate a process switch, we ask the child to notify the
// listeners that we have completed. If the switch promise then gets
// rejected we also cancel the parent, which results in this being called.

View File

@ -1,5 +0,0 @@
[frame-ancestors-from-serviceworker.https.html]
[A 'frame-ancestors' CSP directive set from a serviceworker response with a value 'none' should block rendering.]
expected:
if fission: FAIL