mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1206961 - Use channel->AsyncOpen2() in image/imgLoader.cpp; removing security checks from the callsite reveals that we have to pass the accurate contentPolicyType to ValidateEntry (r=seth,bz)
This commit is contained in:
parent
4b3726dd99
commit
0e1d963860
@ -594,7 +594,8 @@ ShouldRevalidateEntry(imgCacheEntry* aEntry,
|
||||
static bool
|
||||
ShouldLoadCachedImage(imgRequest* aImgRequest,
|
||||
nsISupports* aLoadingContext,
|
||||
nsIPrincipal* aLoadingPrincipal)
|
||||
nsIPrincipal* aLoadingPrincipal,
|
||||
nsContentPolicyType aPolicyType)
|
||||
{
|
||||
/* Call content policies on cached images - Bug 1082837
|
||||
* Cached images are keyed off of the first uri in a redirect chain.
|
||||
@ -611,7 +612,7 @@ ShouldLoadCachedImage(imgRequest* aImgRequest,
|
||||
nsresult rv;
|
||||
|
||||
int16_t decision = nsIContentPolicy::REJECT_REQUEST;
|
||||
rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_INTERNAL_IMAGE,
|
||||
rv = NS_CheckContentLoadPolicy(aPolicyType,
|
||||
contentLocation,
|
||||
aLoadingPrincipal,
|
||||
aLoadingContext,
|
||||
@ -638,7 +639,7 @@ ShouldLoadCachedImage(imgRequest* aImgRequest,
|
||||
// reset the decision for mixed content blocker check
|
||||
decision = nsIContentPolicy::REJECT_REQUEST;
|
||||
rv = nsMixedContentBlocker::ShouldLoad(insecureRedirect,
|
||||
nsIContentPolicy::TYPE_IMAGE,
|
||||
aPolicyType,
|
||||
contentLocation,
|
||||
requestingLocation,
|
||||
aLoadingContext,
|
||||
@ -662,7 +663,8 @@ ShouldLoadCachedImage(imgRequest* aImgRequest,
|
||||
static bool
|
||||
ValidateSecurityInfo(imgRequest* request, bool forcePrincipalCheck,
|
||||
int32_t corsmode, nsIPrincipal* loadingPrincipal,
|
||||
nsISupports* aCX, ReferrerPolicy referrerPolicy)
|
||||
nsISupports* aCX, nsContentPolicyType aPolicyType,
|
||||
ReferrerPolicy referrerPolicy)
|
||||
{
|
||||
// If the entry's Referrer Policy doesn't match, we can't use this request.
|
||||
// XXX: this will return false if an image has different referrer attributes,
|
||||
@ -696,7 +698,7 @@ ValidateSecurityInfo(imgRequest* request, bool forcePrincipalCheck,
|
||||
}
|
||||
|
||||
// Content Policy Check on Cached Images
|
||||
return ShouldLoadCachedImage(request, aCX, loadingPrincipal);
|
||||
return ShouldLoadCachedImage(request, aCX, loadingPrincipal, aPolicyType);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
@ -710,6 +712,7 @@ NewImageChannel(nsIChannel** aResult,
|
||||
bool* aForcePrincipalCheckForCacheEntry,
|
||||
nsIURI* aURI,
|
||||
nsIURI* aInitialDocumentURI,
|
||||
int32_t aCORSMode,
|
||||
nsIURI* aReferringURI,
|
||||
ReferrerPolicy aReferrerPolicy,
|
||||
nsILoadGroup* aLoadGroup,
|
||||
@ -746,24 +749,18 @@ NewImageChannel(nsIChannel** aResult,
|
||||
//
|
||||
aLoadFlags |= nsIChannel::LOAD_CLASSIFY_URI;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> triggeringPrincipal = aLoadingPrincipal;
|
||||
bool isSandBoxed = false;
|
||||
// only inherit if we have a principal
|
||||
bool inherit = false;
|
||||
if (triggeringPrincipal) {
|
||||
inherit = nsContentUtils::
|
||||
ChannelShouldInheritPrincipal(triggeringPrincipal,
|
||||
aURI,
|
||||
false, // aInheritForAboutBlank
|
||||
false); // aForceInherit
|
||||
} else {
|
||||
triggeringPrincipal = nsContentUtils::GetSystemPrincipal();
|
||||
}
|
||||
nsCOMPtr<nsINode> requestingNode = do_QueryInterface(aRequestingContext);
|
||||
nsSecurityFlags securityFlags = nsILoadInfo::SEC_NORMAL;
|
||||
if (inherit) {
|
||||
securityFlags |= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
|
||||
|
||||
nsSecurityFlags securityFlags =
|
||||
aCORSMode == imgIRequest::CORS_NONE
|
||||
? nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS
|
||||
: nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
|
||||
if (aCORSMode == imgIRequest::CORS_ANONYMOUS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_SAME_ORIGIN;
|
||||
} else if (aCORSMode == imgIRequest::CORS_USE_CREDENTIALS) {
|
||||
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
|
||||
}
|
||||
securityFlags |= nsILoadInfo::SEC_ALLOW_CHROME;
|
||||
|
||||
if (aRespectPrivacy) {
|
||||
securityFlags |= nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING;
|
||||
@ -773,11 +770,11 @@ NewImageChannel(nsIChannel** aResult,
|
||||
// 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 of the user stylesheet.
|
||||
if (requestingNode) {
|
||||
if (requestingNode && aLoadingPrincipal) {
|
||||
rv = NS_NewChannelWithTriggeringPrincipal(aResult,
|
||||
aURI,
|
||||
requestingNode,
|
||||
triggeringPrincipal,
|
||||
aLoadingPrincipal,
|
||||
securityFlags,
|
||||
aPolicyType,
|
||||
nullptr, // loadGroup
|
||||
@ -786,14 +783,14 @@ NewImageChannel(nsIChannel** aResult,
|
||||
} else {
|
||||
// either we are loading something inside a document, in which case
|
||||
// we should always have a requestingNode, or we are loading something
|
||||
// outside a document, in which case the triggeringPrincipal
|
||||
// should always be the systemPrincipal.
|
||||
// outside a document, in which case the loadingPrincipal and
|
||||
// triggeringPrincipal should always be the systemPrincipal.
|
||||
// However, there are two exceptions: one is Notifications and the
|
||||
// other one is Favicons which create a channel in the parent prcoess
|
||||
// in which case we can't get a requestingNode.
|
||||
rv = NS_NewChannel(aResult,
|
||||
aURI,
|
||||
triggeringPrincipal,
|
||||
nsContentUtils::GetSystemPrincipal(),
|
||||
securityFlags,
|
||||
aPolicyType,
|
||||
nullptr, // loadGroup
|
||||
@ -805,7 +802,14 @@ NewImageChannel(nsIChannel** aResult,
|
||||
return rv;
|
||||
}
|
||||
|
||||
*aForcePrincipalCheckForCacheEntry = inherit && !isSandBoxed;
|
||||
// only inherit if we have a principal
|
||||
*aForcePrincipalCheckForCacheEntry =
|
||||
aLoadingPrincipal &&
|
||||
nsContentUtils::ChannelShouldInheritPrincipal(
|
||||
aLoadingPrincipal,
|
||||
aURI,
|
||||
/* aInheritForAboutBlank */ false,
|
||||
/* aForceInherit */ false);
|
||||
|
||||
// Initialize HTTP-specific attributes
|
||||
newHttpChannel = do_QueryInterface(*aResult);
|
||||
@ -1634,6 +1638,7 @@ imgLoader::ValidateRequestWithNewChannel(imgRequest* request,
|
||||
&forcePrincipalCheck,
|
||||
aURI,
|
||||
aInitialDocumentURI,
|
||||
aCORSMode,
|
||||
aReferrerURI,
|
||||
aReferrerPolicy,
|
||||
aLoadGroup,
|
||||
@ -1675,18 +1680,6 @@ imgLoader::ValidateRequestWithNewChannel(imgRequest* request,
|
||||
// notification callbacks.
|
||||
newChannel->SetNotificationCallbacks(hvc);
|
||||
|
||||
if (aCORSMode != imgIRequest::CORS_NONE) {
|
||||
bool withCredentials = aCORSMode == imgIRequest::CORS_USE_CREDENTIALS;
|
||||
RefPtr<nsCORSListenerProxy> corsproxy =
|
||||
new nsCORSListenerProxy(listener, aLoadingPrincipal, withCredentials);
|
||||
rv = corsproxy->Init(newChannel, DataURIHandling::Allow);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
listener = corsproxy;
|
||||
}
|
||||
|
||||
request->SetValidator(hvc);
|
||||
|
||||
// We will send notifications from imgCacheValidator::OnStartRequest().
|
||||
@ -1701,7 +1694,7 @@ imgLoader::ValidateRequestWithNewChannel(imgRequest* request,
|
||||
mozilla::net::PredictorLearn(aURI, aInitialDocumentURI,
|
||||
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE, aLoadGroup);
|
||||
|
||||
rv = newChannel->AsyncOpen(listener, nullptr);
|
||||
rv = newChannel->AsyncOpen2(listener);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return false;
|
||||
}
|
||||
@ -1765,7 +1758,7 @@ imgLoader::ValidateEntry(imgCacheEntry* aEntry,
|
||||
|
||||
if (!ValidateSecurityInfo(request, aEntry->ForcePrincipalCheck(),
|
||||
aCORSMode, aLoadingPrincipal,
|
||||
aCX, aReferrerPolicy))
|
||||
aCX, aLoadPolicyType, aReferrerPolicy))
|
||||
return false;
|
||||
|
||||
// data URIs are immutable and by their nature can't leak data, so we can
|
||||
@ -2170,6 +2163,7 @@ imgLoader::LoadImage(nsIURI* aURI,
|
||||
&forcePrincipalCheck,
|
||||
aURI,
|
||||
aInitialDocumentURI,
|
||||
corsmode,
|
||||
aReferrerURI,
|
||||
aReferrerPolicy,
|
||||
aLoadGroup,
|
||||
@ -2206,43 +2200,20 @@ imgLoader::LoadImage(nsIURI* aURI,
|
||||
}
|
||||
|
||||
// create the proxy listener
|
||||
nsCOMPtr<nsIStreamListener> pl = new ProxyListener(request.get());
|
||||
|
||||
// See if we need to insert a CORS proxy between the proxy listener and the
|
||||
// request.
|
||||
nsCOMPtr<nsIStreamListener> listener = pl;
|
||||
if (corsmode != imgIRequest::CORS_NONE) {
|
||||
MOZ_LOG(gImgLog, LogLevel::Debug,
|
||||
("[this=%p] imgLoader::LoadImage -- Setting up a CORS load",
|
||||
this));
|
||||
bool withCredentials = corsmode == imgIRequest::CORS_USE_CREDENTIALS;
|
||||
|
||||
RefPtr<nsCORSListenerProxy> corsproxy =
|
||||
new nsCORSListenerProxy(pl, aLoadingPrincipal, withCredentials);
|
||||
rv = corsproxy->Init(newChannel, DataURIHandling::Allow);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_LOG(gImgLog, LogLevel::Debug,
|
||||
("[this=%p] imgLoader::LoadImage -- nsCORSListenerProxy "
|
||||
"creation failed: 0x%x\n", this, rv));
|
||||
request->CancelAndAbort(rv);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
listener = corsproxy;
|
||||
}
|
||||
nsCOMPtr<nsIStreamListener> listener = new ProxyListener(request.get());
|
||||
|
||||
MOZ_LOG(gImgLog, LogLevel::Debug,
|
||||
("[this=%p] imgLoader::LoadImage -- Calling channel->AsyncOpen()\n",
|
||||
("[this=%p] imgLoader::LoadImage -- Calling channel->AsyncOpen2()\n",
|
||||
this));
|
||||
|
||||
mozilla::net::PredictorLearn(aURI, aInitialDocumentURI,
|
||||
nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE, aLoadGroup);
|
||||
|
||||
nsresult openRes = newChannel->AsyncOpen(listener, nullptr);
|
||||
nsresult openRes = newChannel->AsyncOpen2(listener);
|
||||
|
||||
if (NS_FAILED(openRes)) {
|
||||
MOZ_LOG(gImgLog, LogLevel::Debug,
|
||||
("[this=%p] imgLoader::LoadImage -- AsyncOpen() failed: 0x%x\n",
|
||||
("[this=%p] imgLoader::LoadImage -- AsyncOpen2() failed: 0x%x\n",
|
||||
this, openRes));
|
||||
request->CancelAndAbort(openRes);
|
||||
return openRes;
|
||||
@ -2373,9 +2344,17 @@ imgLoader::LoadImageWithChannel(nsIChannel* channel,
|
||||
//
|
||||
// Since aCanMakeNewChannel == false, we don't need to pass content policy
|
||||
// type/principal/etc
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
|
||||
// if there is a loadInfo, use the right contentType, otherwise
|
||||
// default to the internal image type
|
||||
nsContentPolicyType policyType = loadInfo
|
||||
? loadInfo->InternalContentPolicyType()
|
||||
: nsIContentPolicy::TYPE_INTERNAL_IMAGE;
|
||||
|
||||
if (ValidateEntry(entry, uri, nullptr, nullptr, RP_Default,
|
||||
nullptr, aObserver, aCX, requestFlags,
|
||||
nsIContentPolicy::TYPE_INVALID, false, nullptr,
|
||||
policyType, false, nullptr,
|
||||
nullptr, imgIRequest::CORS_NONE)) {
|
||||
request = entry->GetRequest();
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user