Bug 1038756: Refactor SetUpChannelOwner to ChannelShouldInheritPrincipal (r=bz)
This commit is contained in:
@@ -1965,26 +1965,21 @@ public:
|
||||
static nsresult URIInheritsSecurityContext(nsIURI *aURI, bool *aResult);
|
||||
|
||||
/**
|
||||
* Set the given principal as the principal on the nsILoadInfo of the given
|
||||
* channel, and tell the channel to inherit it if needed. aPrincipal may be
|
||||
* null, in which case this method is a no-op.
|
||||
* Called before a channel is created to query whether the new
|
||||
* channel should inherit the principal.
|
||||
*
|
||||
* If aLoadingPrincipal is not null, aURI must be the URI of aChannel. If
|
||||
* aInheritForAboutBlank is true, then about:blank will be told to inherit the
|
||||
* principal. If aForceInherit is true, the channel will be told to inherit
|
||||
* the principal no matter what, as long as the principal is not null.
|
||||
* The argument aLoadingPrincipal must not be null. The argument
|
||||
* aURI must be the URI of the new channel. If aInheritForAboutBlank
|
||||
* is true, then about:blank will be told to inherit the principal.
|
||||
* If aForceInherit is true, the new channel will be told to inherit
|
||||
* the principal no matter what.
|
||||
*
|
||||
* If aIsSandboxed is true, then aLoadingPrincipal must not be null. In this
|
||||
* case, the owner on the channel, if any, will be reset to null and the
|
||||
* nsILoadInfo will say the channel should be sandboxed.
|
||||
*
|
||||
* The return value is whether the channel was told to inherit the principal.
|
||||
* The return value is whether the new channel should inherit
|
||||
* the principal.
|
||||
*/
|
||||
static bool SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
|
||||
nsIChannel* aChannel,
|
||||
static bool ChannelShouldInheritPrincipal(nsIPrincipal* aLoadingPrincipal,
|
||||
nsIURI* aURI,
|
||||
bool aInheritForAboutBlank,
|
||||
bool aIsSandboxed,
|
||||
bool aForceInherit);
|
||||
|
||||
static nsresult Btoa(const nsAString& aBinaryData,
|
||||
|
||||
@@ -6440,37 +6440,14 @@ nsContentUtils::URIInheritsSecurityContext(nsIURI *aURI, bool *aResult)
|
||||
|
||||
// static
|
||||
bool
|
||||
nsContentUtils::SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
|
||||
nsIChannel* aChannel,
|
||||
nsContentUtils::ChannelShouldInheritPrincipal(nsIPrincipal* aLoadingPrincipal,
|
||||
nsIURI* aURI,
|
||||
bool aInheritForAboutBlank,
|
||||
bool aIsSandboxed,
|
||||
bool aForceInherit)
|
||||
{
|
||||
nsCOMPtr<nsIPrincipal> loadingPrincipal = aLoadingPrincipal;
|
||||
if (!loadingPrincipal) {
|
||||
if (!aIsSandboxed) {
|
||||
// Nothing to do here
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(aLoadingPrincipal, "Can not check inheritance without a principal");
|
||||
|
||||
// Go ahead and create a nullprincipal to use as our loading principal,
|
||||
// since we need to make sure to sandbox the load but we have no clue who's
|
||||
// loading us.
|
||||
loadingPrincipal = do_CreateInstance(NS_NULLPRINCIPAL_CONTRACTID);
|
||||
if (!loadingPrincipal) {
|
||||
NS_RUNTIMEABORT("Failed to create a principal?");
|
||||
}
|
||||
}
|
||||
|
||||
// If we're sandboxed, make sure to clear any owner the channel
|
||||
// might already have.
|
||||
if (aIsSandboxed) {
|
||||
aChannel->SetOwner(nullptr);
|
||||
}
|
||||
|
||||
// Set the loadInfo of the channel, but only tell the channel to
|
||||
// inherit if it can't provide its own security context.
|
||||
// Only tell the channel to inherit if it can't provide its own security context.
|
||||
//
|
||||
// XXX: If this is ever changed, check all callers for what owners
|
||||
// they're passing in. In particular, see the code and
|
||||
@@ -6500,19 +6477,12 @@ nsContentUtils::SetUpChannelOwner(nsIPrincipal* aLoadingPrincipal,
|
||||
// based on its own codebase later.
|
||||
//
|
||||
(URIIsLocalFile(aURI) &&
|
||||
NS_SUCCEEDED(loadingPrincipal->CheckMayLoad(aURI, false, false)) &&
|
||||
NS_SUCCEEDED(aLoadingPrincipal->CheckMayLoad(aURI, false, false)) &&
|
||||
// One more check here. CheckMayLoad will always return true for the
|
||||
// system principal, but we do NOT want to inherit in that case.
|
||||
!IsSystemPrincipal(loadingPrincipal));
|
||||
!IsSystemPrincipal(aLoadingPrincipal));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo =
|
||||
new LoadInfo(loadingPrincipal,
|
||||
inherit ?
|
||||
nsILoadInfo::eInheritPrincipal : nsILoadInfo::eDontInheritPrincipal,
|
||||
aIsSandboxed ? nsILoadInfo::eSandboxed : nsILoadInfo::eNotSandboxed);
|
||||
aChannel->SetLoadInfo(loadInfo);
|
||||
return inherit && !aIsSandboxed;
|
||||
return inherit;
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
||||
@@ -2504,10 +2504,23 @@ nsObjectLoadingContent::OpenChannel()
|
||||
nsRefPtr<ObjectInterfaceRequestorShim> shim =
|
||||
new ObjectInterfaceRequestorShim(this);
|
||||
|
||||
bool isSandBoxed = doc->GetSandboxFlags() & SANDBOXED_ORIGIN;
|
||||
bool inherit = nsContentUtils::ChannelShouldInheritPrincipal(thisContent->NodePrincipal(),
|
||||
mURI,
|
||||
true, // aInheritForAboutBlank
|
||||
false); // aForceInherit
|
||||
nsSecurityFlags securityFlags = nsILoadInfo::SEC_NORMAL;
|
||||
if (inherit) {
|
||||
securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
|
||||
}
|
||||
if (isSandBoxed) {
|
||||
securityFlags |= nsILoadInfo::SEC_SANDBOXED;
|
||||
}
|
||||
|
||||
rv = NS_NewChannel(getter_AddRefs(chan),
|
||||
mURI,
|
||||
thisContent,
|
||||
nsILoadInfo::SEC_NORMAL,
|
||||
securityFlags,
|
||||
nsIContentPolicy::TYPE_OBJECT,
|
||||
channelPolicy,
|
||||
group, // aLoadGroup
|
||||
@@ -2529,14 +2542,6 @@ nsObjectLoadingContent::OpenChannel()
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the channel's principal and such, like nsDocShell::DoURILoad does.
|
||||
// If the content being loaded should be sandboxed with respect to origin we
|
||||
// tell SetUpChannelOwner that.
|
||||
nsContentUtils::SetUpChannelOwner(thisContent->NodePrincipal(), chan, mURI,
|
||||
true,
|
||||
doc->GetSandboxFlags() & SANDBOXED_ORIGIN,
|
||||
false);
|
||||
|
||||
nsCOMPtr<nsIScriptChannel> scriptChannel = do_QueryInterface(chan);
|
||||
if (scriptChannel) {
|
||||
// Allow execution against our context if the principals match
|
||||
|
||||
@@ -9369,7 +9369,7 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
{
|
||||
bool willInherit;
|
||||
// This condition needs to match the one in
|
||||
// nsContentUtils::SetUpChannelOwner.
|
||||
// nsContentUtils::ChannelShouldInheritPrincipal.
|
||||
// Except we reverse the rv check to be safe in case
|
||||
// nsContentUtils::URIInheritsSecurityContext fails here and
|
||||
// succeeds there.
|
||||
@@ -10147,8 +10147,19 @@ nsDocShell::DoURILoad(nsIURI * aURI,
|
||||
requestingNode = mScriptGlobal->GetExtantDoc();
|
||||
}
|
||||
}
|
||||
|
||||
bool isSandBoxed = mSandboxFlags & SANDBOXED_ORIGIN;
|
||||
// only inherit if we have a requestingPrincipal
|
||||
bool inherit = false;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> requestingPrincipal = do_QueryInterface(aOwner);
|
||||
if (!requestingPrincipal && aReferrerURI) {
|
||||
if (requestingPrincipal) {
|
||||
inherit = nsContentUtils::ChannelShouldInheritPrincipal(requestingPrincipal,
|
||||
aURI,
|
||||
true, // aInheritForAboutBlank
|
||||
isSrcdoc);
|
||||
}
|
||||
else if (!requestingPrincipal && aReferrerURI) {
|
||||
rv = CreatePrincipalFromReferrer(aReferrerURI,
|
||||
getter_AddRefs(requestingPrincipal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@@ -10157,12 +10168,20 @@ nsDocShell::DoURILoad(nsIURI * aURI,
|
||||
requestingPrincipal = nsContentUtils::GetSystemPrincipal();
|
||||
}
|
||||
|
||||
nsSecurityFlags securityFlags = nsILoadInfo::SEC_NORMAL;
|
||||
if (inherit) {
|
||||
securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
|
||||
}
|
||||
if (isSandBoxed) {
|
||||
securityFlags |= nsILoadInfo::SEC_SANDBOXED;
|
||||
}
|
||||
|
||||
if (!isSrcdoc) {
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(channel),
|
||||
aURI,
|
||||
requestingNode,
|
||||
requestingPrincipal,
|
||||
nsILoadInfo::SEC_NORMAL,
|
||||
securityFlags,
|
||||
aContentPolicyType,
|
||||
channelPolicy,
|
||||
nullptr, // loadGroup
|
||||
@@ -10221,7 +10240,7 @@ nsDocShell::DoURILoad(nsIURI * aURI,
|
||||
nsCOMPtr<nsILoadInfo> loadInfo =
|
||||
new LoadInfo(requestingPrincipal,
|
||||
requestingNode,
|
||||
nsILoadInfo::SEC_NORMAL,
|
||||
securityFlags,
|
||||
aContentPolicyType);
|
||||
channel->SetLoadInfo(loadInfo);
|
||||
}
|
||||
@@ -10386,11 +10405,6 @@ nsDocShell::DoURILoad(nsIURI * aURI,
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> ownerPrincipal = do_QueryInterface(aOwner);
|
||||
nsContentUtils::SetUpChannelOwner(ownerPrincipal, channel, aURI, true,
|
||||
mSandboxFlags & SANDBOXED_ORIGIN,
|
||||
isSrcdoc);
|
||||
|
||||
nsCOMPtr<nsIScriptChannel> scriptChannel = do_QueryInterface(channel);
|
||||
if (scriptChannel) {
|
||||
// Allow execution against our context if the principals match
|
||||
|
||||
@@ -663,10 +663,23 @@ static nsresult NewImageChannel(nsIChannel **aResult,
|
||||
aLoadFlags |= nsIChannel::LOAD_CLASSIFY_URI;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> requestingPrincipal = aLoadingPrincipal;
|
||||
if (!requestingPrincipal) {
|
||||
bool isSandBoxed = false;
|
||||
// only inherit if we have a principal
|
||||
bool inherit = false;
|
||||
if (requestingPrincipal) {
|
||||
inherit = nsContentUtils::ChannelShouldInheritPrincipal(requestingPrincipal,
|
||||
aURI,
|
||||
false, // aInheritForAboutBlank
|
||||
false); // aForceInherit
|
||||
}
|
||||
else {
|
||||
requestingPrincipal = nsContentUtils::GetSystemPrincipal();
|
||||
}
|
||||
nsCOMPtr<nsINode> requestingNode = do_QueryInterface(aRequestingContext);
|
||||
nsSecurityFlags securityFlags = nsILoadInfo::SEC_NORMAL;
|
||||
if (inherit) {
|
||||
securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
|
||||
}
|
||||
// Note we are calling NS_NewChannelInternal() here with a node and a principal.
|
||||
// This is for things like background images that are specified by user
|
||||
// stylesheets, where the document is being styled, but the principal is that
|
||||
@@ -675,7 +688,7 @@ static nsresult NewImageChannel(nsIChannel **aResult,
|
||||
aURI,
|
||||
requestingNode,
|
||||
requestingPrincipal,
|
||||
nsILoadInfo::SEC_NORMAL,
|
||||
securityFlags,
|
||||
nsIContentPolicy::TYPE_IMAGE,
|
||||
aPolicy,
|
||||
nullptr, // loadGroup
|
||||
@@ -685,7 +698,7 @@ static nsresult NewImageChannel(nsIChannel **aResult,
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
*aForcePrincipalCheckForCacheEntry = false;
|
||||
*aForcePrincipalCheckForCacheEntry = inherit && !isSandBoxed;
|
||||
|
||||
// Initialize HTTP-specific attributes
|
||||
newHttpChannel = do_QueryInterface(*aResult);
|
||||
@@ -711,11 +724,6 @@ static nsresult NewImageChannel(nsIChannel **aResult,
|
||||
p->AdjustPriority(priority);
|
||||
}
|
||||
|
||||
bool setOwner = nsContentUtils::SetUpChannelOwner(aLoadingPrincipal,
|
||||
*aResult, aURI, false,
|
||||
false, false);
|
||||
*aForcePrincipalCheckForCacheEntry = setOwner;
|
||||
|
||||
// Create a new loadgroup for this new channel, using the old group as
|
||||
// the parent. The indirection keeps the channel insulated from cancels,
|
||||
// but does allow a way for this revalidation to be associated with at
|
||||
|
||||
@@ -246,6 +246,12 @@ NS_NewChannelInternal(nsIChannel** outChannel,
|
||||
|
||||
channel->SetLoadInfo(aLoadInfo);
|
||||
|
||||
// If we're sandboxed, make sure to clear any owner the channel
|
||||
// might already have.
|
||||
if (aLoadInfo->GetLoadingSandboxed()) {
|
||||
channel->SetOwner(nullptr);
|
||||
}
|
||||
|
||||
channel.forget(outChannel);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user