mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 663570 - MetaCSP Part 3: Upgrade insecure requests changes (r=bz)
This commit is contained in:
parent
b967444f19
commit
d9f1276ace
@ -1441,6 +1441,7 @@ nsIDocument::nsIDocument()
|
||||
mReferrerPolicySet(false),
|
||||
mReferrerPolicy(mozilla::net::RP_Default),
|
||||
mUpgradeInsecureRequests(false),
|
||||
mUpgradeInsecurePreloads(false),
|
||||
mCharacterSet(NS_LITERAL_CSTRING("ISO-8859-1")),
|
||||
mNodeInfoManager(nullptr),
|
||||
mCompatMode(eCompatibility_FullStandards),
|
||||
@ -2574,6 +2575,8 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
if (sameTypeParent) {
|
||||
mUpgradeInsecureRequests =
|
||||
sameTypeParent->GetDocument()->GetUpgradeInsecureRequests();
|
||||
mUpgradeInsecurePreloads =
|
||||
sameTypeParent->GetDocument()->GetUpgradeInsecurePreloads();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2653,6 +2656,58 @@ nsDocument::IsLoopDocument(nsIChannel *aChannel)
|
||||
return isLoop;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::ApplySettingsFromCSP(bool aSpeculative)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!aSpeculative) {
|
||||
// 1) apply settings from regular CSP
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
rv = NodePrincipal()->GetCsp(getter_AddRefs(csp));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
if (csp) {
|
||||
// Set up any Referrer Policy specified by CSP
|
||||
bool hasReferrerPolicy = false;
|
||||
uint32_t referrerPolicy = mozilla::net::RP_Default;
|
||||
rv = csp->GetReferrerPolicy(&referrerPolicy, &hasReferrerPolicy);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
if (hasReferrerPolicy) {
|
||||
mReferrerPolicy = static_cast<ReferrerPolicy>(referrerPolicy);
|
||||
mReferrerPolicySet = true;
|
||||
}
|
||||
|
||||
// Set up 'upgrade-insecure-requests' if not already inherited
|
||||
// from the parent context or set by any other CSP.
|
||||
if (!mUpgradeInsecureRequests) {
|
||||
rv = csp->GetUpgradeInsecureRequests(&mUpgradeInsecureRequests);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 2) apply settings from speculative csp
|
||||
nsCOMPtr<nsIContentSecurityPolicy> preloadCsp;
|
||||
rv = NodePrincipal()->GetPreloadCsp(getter_AddRefs(preloadCsp));
|
||||
if (preloadCsp) {
|
||||
// Set up any Referrer Policy specified by CSP
|
||||
bool hasReferrerPolicy = false;
|
||||
uint32_t referrerPolicy = mozilla::net::RP_Default;
|
||||
rv = preloadCsp->GetReferrerPolicy(&referrerPolicy, &hasReferrerPolicy);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
if (hasReferrerPolicy) {
|
||||
// please note that referrer policy spec defines that the latest
|
||||
// policy awlays wins, hence we can safely overwrite the policy here.
|
||||
mReferrerPolicy = static_cast<ReferrerPolicy>(referrerPolicy);
|
||||
mReferrerPolicySet = true;
|
||||
}
|
||||
if (!mUpgradeInsecurePreloads) {
|
||||
rv = preloadCsp->GetUpgradeInsecureRequests(&mUpgradeInsecurePreloads);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
{
|
||||
@ -2815,34 +2870,13 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
||||
}
|
||||
}
|
||||
|
||||
// ----- Set up any Referrer Policy specified by CSP
|
||||
bool hasReferrerPolicy = false;
|
||||
uint32_t referrerPolicy = mozilla::net::RP_Default;
|
||||
rv = csp->GetReferrerPolicy(&referrerPolicy, &hasReferrerPolicy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasReferrerPolicy) {
|
||||
// Referrer policy spec (section 6.1) says that we always use the newest
|
||||
// referrer policy we find
|
||||
mReferrerPolicy = static_cast<ReferrerPolicy>(referrerPolicy);
|
||||
mReferrerPolicySet = true;
|
||||
|
||||
// Referrer Policy is set separately for the speculative parser in
|
||||
// nsHTMLDocument::StartDocumentLoad() so there's nothing to do here for
|
||||
// speculative loads.
|
||||
}
|
||||
|
||||
// ------ Set flag for 'upgrade-insecure-requests' if not already
|
||||
// inherited from the parent context.
|
||||
if (!mUpgradeInsecureRequests) {
|
||||
rv = csp->GetUpgradeInsecureRequests(&mUpgradeInsecureRequests);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = principal->SetCsp(csp);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
MOZ_LOG(gCspPRLog, LogLevel::Debug,
|
||||
("Inserted CSP into principal %p", principal));
|
||||
|
||||
ApplySettingsFromCSP(false);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -717,6 +717,8 @@ public:
|
||||
|
||||
virtual void SetChromeXHRDocBaseURI(nsIURI* aURI) override;
|
||||
|
||||
virtual void ApplySettingsFromCSP(bool aSpeculative) override;
|
||||
|
||||
/**
|
||||
* Set the principal responsible for this document.
|
||||
*/
|
||||
|
@ -296,6 +296,11 @@ public:
|
||||
*/
|
||||
virtual void SetChromeXHRDocBaseURI(nsIURI* aURI) = 0;
|
||||
|
||||
/**
|
||||
* Set referrer policy and upgrade-insecure-requests flags
|
||||
*/
|
||||
virtual void ApplySettingsFromCSP(bool aSpeculative) = 0;
|
||||
|
||||
/**
|
||||
* Return the referrer policy of the document. Return "default" if there's no
|
||||
* valid meta referrer tag found in the document.
|
||||
@ -325,6 +330,14 @@ public:
|
||||
return mUpgradeInsecureRequests;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as GetUpgradeInsecureRequests() but *only* for preloads.
|
||||
*/
|
||||
bool GetUpgradeInsecurePreloads() const
|
||||
{
|
||||
return mUpgradeInsecurePreloads;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the principal responsible for this document.
|
||||
*/
|
||||
@ -2713,6 +2726,7 @@ protected:
|
||||
ReferrerPolicyEnum mReferrerPolicy;
|
||||
|
||||
bool mUpgradeInsecureRequests;
|
||||
bool mUpgradeInsecurePreloads;
|
||||
|
||||
mozilla::WeakPtr<nsDocShell> mDocumentContainer;
|
||||
|
||||
|
@ -243,6 +243,7 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo,
|
||||
aLoadInfo->GetSecurityFlags(),
|
||||
aLoadInfo->InternalContentPolicyType(),
|
||||
aLoadInfo->GetUpgradeInsecureRequests(),
|
||||
aLoadInfo->GetUpgradeInsecurePreloads(),
|
||||
aLoadInfo->GetInnerWindowID(),
|
||||
aLoadInfo->GetOuterWindowID(),
|
||||
aLoadInfo->GetParentOuterWindowID(),
|
||||
@ -297,6 +298,7 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs,
|
||||
loadInfoArgs.securityFlags(),
|
||||
loadInfoArgs.contentPolicyType(),
|
||||
loadInfoArgs.upgradeInsecureRequests(),
|
||||
loadInfoArgs.upgradeInsecurePreloads(),
|
||||
loadInfoArgs.innerWindowID(),
|
||||
loadInfoArgs.outerWindowID(),
|
||||
loadInfoArgs.parentOuterWindowID(),
|
||||
|
@ -33,6 +33,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
|
||||
, mInternalContentPolicyType(aContentPolicyType)
|
||||
, mTainting(LoadTainting::Basic)
|
||||
, mUpgradeInsecureRequests(false)
|
||||
, mUpgradeInsecurePreloads(false)
|
||||
, mInnerWindowID(0)
|
||||
, mOuterWindowID(0)
|
||||
, mParentOuterWindowID(0)
|
||||
@ -79,6 +80,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
|
||||
}
|
||||
|
||||
mUpgradeInsecureRequests = aLoadingContext->OwnerDoc()->GetUpgradeInsecureRequests();
|
||||
mUpgradeInsecurePreloads = aLoadingContext->OwnerDoc()->GetUpgradeInsecurePreloads();
|
||||
}
|
||||
|
||||
mOriginAttributes = BasePrincipal::Cast(mLoadingPrincipal)->OriginAttributesRef();
|
||||
@ -92,6 +94,7 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
|
||||
, mInternalContentPolicyType(rhs.mInternalContentPolicyType)
|
||||
, mTainting(rhs.mTainting)
|
||||
, mUpgradeInsecureRequests(rhs.mUpgradeInsecureRequests)
|
||||
, mUpgradeInsecurePreloads(rhs.mUpgradeInsecurePreloads)
|
||||
, mInnerWindowID(rhs.mInnerWindowID)
|
||||
, mOuterWindowID(rhs.mOuterWindowID)
|
||||
, mParentOuterWindowID(rhs.mParentOuterWindowID)
|
||||
@ -109,6 +112,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
|
||||
nsSecurityFlags aSecurityFlags,
|
||||
nsContentPolicyType aContentPolicyType,
|
||||
bool aUpgradeInsecureRequests,
|
||||
bool aUpgradeInsecurePreloads,
|
||||
uint64_t aInnerWindowID,
|
||||
uint64_t aOuterWindowID,
|
||||
uint64_t aParentOuterWindowID,
|
||||
@ -122,6 +126,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
|
||||
, mSecurityFlags(aSecurityFlags)
|
||||
, mInternalContentPolicyType(aContentPolicyType)
|
||||
, mUpgradeInsecureRequests(aUpgradeInsecureRequests)
|
||||
, mUpgradeInsecurePreloads(aUpgradeInsecurePreloads)
|
||||
, mInnerWindowID(aInnerWindowID)
|
||||
, mOuterWindowID(aOuterWindowID)
|
||||
, mParentOuterWindowID(aParentOuterWindowID)
|
||||
@ -292,6 +297,13 @@ LoadInfo::GetUpgradeInsecureRequests(bool* aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LoadInfo::GetUpgradeInsecurePreloads(bool* aResult)
|
||||
{
|
||||
*aResult = mUpgradeInsecurePreloads;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LoadInfo::GetInnerWindowID(uint64_t* aResult)
|
||||
{
|
||||
|
@ -70,6 +70,7 @@ private:
|
||||
nsSecurityFlags aSecurityFlags,
|
||||
nsContentPolicyType aContentPolicyType,
|
||||
bool aUpgradeInsecureRequests,
|
||||
bool aUpgradeInsecurePreloads,
|
||||
uint64_t aInnerWindowID,
|
||||
uint64_t aOuterWindowID,
|
||||
uint64_t aParentOuterWindowID,
|
||||
@ -101,6 +102,7 @@ private:
|
||||
nsContentPolicyType mInternalContentPolicyType;
|
||||
LoadTainting mTainting;
|
||||
bool mUpgradeInsecureRequests;
|
||||
bool mUpgradeInsecurePreloads;
|
||||
uint64_t mInnerWindowID;
|
||||
uint64_t mOuterWindowID;
|
||||
uint64_t mParentOuterWindowID;
|
||||
|
@ -26,7 +26,7 @@ typedef unsigned long nsSecurityFlags;
|
||||
/**
|
||||
* An nsILoadOwner represents per-load information about who started the load.
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(45a4a9e1-b50d-468a-a01c-43de5c38c8db)]
|
||||
[scriptable, builtinclass, uuid(542b38c6-1c7b-4630-bd6b-9fee0d1b474d)]
|
||||
interface nsILoadInfo : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -295,6 +295,11 @@ interface nsILoadInfo : nsISupports
|
||||
*/
|
||||
[infallible] readonly attribute boolean upgradeInsecureRequests;
|
||||
|
||||
/**
|
||||
* Same as upgradeInsecureRequests but for preloads.
|
||||
*/
|
||||
[infallible] readonly attribute boolean upgradeInsecurePreloads;
|
||||
|
||||
/**
|
||||
* Typically these are the window IDs of the window in which the element being
|
||||
* loaded lives. However, if the element being loaded is <frame
|
||||
|
@ -31,6 +31,7 @@ struct LoadInfoArgs
|
||||
uint32_t securityFlags;
|
||||
uint32_t contentPolicyType;
|
||||
bool upgradeInsecureRequests;
|
||||
bool upgradeInsecurePreloads;
|
||||
uint64_t innerWindowID;
|
||||
uint64_t outerWindowID;
|
||||
uint64_t parentOuterWindowID;
|
||||
|
@ -332,7 +332,15 @@ nsHttpChannel::Connect()
|
||||
// the CSP directive 'upgrade-insecure-requests', then it's time to fulfill
|
||||
// the promise to CSP and mixed content blocking to upgrade the channel
|
||||
// from http to https.
|
||||
if (mLoadInfo && mLoadInfo->GetUpgradeInsecureRequests()) {
|
||||
if (mLoadInfo) {
|
||||
bool isPreload =
|
||||
(mLoadInfo->InternalContentPolicyType() == nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD ||
|
||||
mLoadInfo->InternalContentPolicyType() == nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD ||
|
||||
mLoadInfo->InternalContentPolicyType() == nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD);
|
||||
bool upgradeRequests =
|
||||
((isPreload && mLoadInfo->GetUpgradeInsecurePreloads()) ||
|
||||
(mLoadInfo->GetUpgradeInsecureRequests()));
|
||||
|
||||
// Please note that cross origin top level navigations are not subject
|
||||
// to upgrade-insecure-requests, see:
|
||||
// http://www.w3.org/TR/upgrade-insecure-requests/#examples
|
||||
@ -343,7 +351,7 @@ nsHttpChannel::Connect()
|
||||
(mLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_DOCUMENT) &&
|
||||
(!resultPrincipal->Equals(mLoadInfo->LoadingPrincipal()));
|
||||
|
||||
if (!crossOriginNavigation) {
|
||||
if (upgradeRequests && !crossOriginNavigation) {
|
||||
// let's log a message to the console that we are upgrading a request
|
||||
nsAutoCString spec, scheme;
|
||||
mURI->GetSpec(spec);
|
||||
|
Loading…
Reference in New Issue
Block a user