mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Bug 1583076 - Make nsCSPService::ConsultCSPForRedirect return both the AsyncOnChannelRedirect result, as well as an optional result to cancel the old channel with. r=ckerschb
Differential Revision: https://phabricator.services.mozilla.com/D46740 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
507bc7d9ba
commit
edbd9409af
@ -296,12 +296,13 @@ CSPService::AsyncOnChannelRedirect(nsIChannel* oldChannel,
|
||||
return rv;
|
||||
}
|
||||
|
||||
int16_t decision = nsIContentPolicy::ACCEPT;
|
||||
rv = ConsultCSPForRedirect(originalUri, newUri, loadInfo, &decision);
|
||||
if (NS_CP_REJECTED(decision)) {
|
||||
Maybe<nsresult> cancelCode;
|
||||
rv = ConsultCSPForRedirect(originalUri, newUri, loadInfo, cancelCode);
|
||||
if (cancelCode) {
|
||||
oldChannel->Cancel(*cancelCode);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
autoCallback.DontCallback();
|
||||
oldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
|
||||
return NS_BINDING_FAILED;
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -310,15 +311,15 @@ CSPService::AsyncOnChannelRedirect(nsIChannel* oldChannel,
|
||||
nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
|
||||
nsIURI* aNewURI,
|
||||
nsILoadInfo* aLoadInfo,
|
||||
int16_t* aDecision) {
|
||||
Maybe<nsresult>& aCancelCode) {
|
||||
nsCOMPtr<nsICSPEventListener> cspEventListener;
|
||||
nsresult rv =
|
||||
aLoadInfo->GetCspEventListener(getter_AddRefs(cspEventListener));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
MOZ_ALWAYS_SUCCEEDS(rv);
|
||||
|
||||
nsAutoString cspNonce;
|
||||
rv = aLoadInfo->GetCspNonce(cspNonce);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
MOZ_ALWAYS_SUCCEEDS(rv);
|
||||
|
||||
nsContentPolicyType policyType = aLoadInfo->InternalContentPolicyType();
|
||||
bool isPreload = nsContentUtils::IsPreloadType(policyType);
|
||||
@ -330,6 +331,7 @@ nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
|
||||
policyType =
|
||||
nsContentUtils::InternalContentPolicyTypeToExternalOrWorker(policyType);
|
||||
|
||||
int16_t decision = nsIContentPolicy::ACCEPT;
|
||||
nsCOMPtr<nsISupports> requestContext = aLoadInfo->GetLoadingContext();
|
||||
// 1) Apply speculative CSP for preloads
|
||||
if (isPreload) {
|
||||
@ -346,12 +348,13 @@ nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
|
||||
aOriginalURI, // Original nsIURI
|
||||
true, // aSendViolationReports
|
||||
cspNonce, // nonce
|
||||
aDecision);
|
||||
&decision);
|
||||
|
||||
// if the preload policy already denied the load, then there
|
||||
// is no point in checking the real policy
|
||||
if (NS_CP_REJECTED(*aDecision)) {
|
||||
return NS_OK;
|
||||
if (NS_CP_REJECTED(decision)) {
|
||||
aCancelCode = Some(NS_ERROR_DOM_BAD_URI);
|
||||
return NS_BINDING_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -369,7 +372,11 @@ nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
|
||||
aOriginalURI, // Original nsIURI
|
||||
true, // aSendViolationReports
|
||||
cspNonce, // nonce
|
||||
aDecision);
|
||||
&decision);
|
||||
if (NS_CP_REJECTED(decision)) {
|
||||
aCancelCode = Some(NS_ERROR_DOM_BAD_URI);
|
||||
return NS_BINDING_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -34,9 +34,13 @@ class CSPService : public nsIContentPolicy, public nsIChannelEventSink {
|
||||
const nsACString& aMimeTypeGuess,
|
||||
int16_t* aDecision);
|
||||
|
||||
// Static helper to check CSP when doing a channel redirect.
|
||||
// Returns the results to returns from
|
||||
// AsyncOnChannelRedirect/nsIAsyncVerifyRedirectCallback. Optionally returns
|
||||
// an nsresult to Cancel the old channel with.
|
||||
static nsresult ConsultCSPForRedirect(nsIURI* aOriginalURI, nsIURI* aNewURI,
|
||||
nsILoadInfo* aLoadInfo,
|
||||
int16_t* aDecision);
|
||||
Maybe<nsresult>& aCancelCode);
|
||||
|
||||
protected:
|
||||
virtual ~CSPService();
|
||||
|
@ -412,22 +412,15 @@ IPCResult DocumentChannelChild::RecvConfirmRedirect(
|
||||
nsCOMPtr<nsIURI> originalUri;
|
||||
nsresult rv = GetOriginalURI(getter_AddRefs(originalUri));
|
||||
if (NS_FAILED(rv)) {
|
||||
aResolve(rv);
|
||||
aResolve(Tuple<const nsresult&, const Maybe<nsresult>&>(NS_BINDING_FAILED,
|
||||
Some(rv)));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
int16_t decision = nsIContentPolicy::ACCEPT;
|
||||
Maybe<nsresult> cancelCode;
|
||||
rv = CSPService::ConsultCSPForRedirect(originalUri, aNewUri, mLoadInfo,
|
||||
&decision);
|
||||
if (NS_FAILED(rv)) {
|
||||
aResolve(rv);
|
||||
return IPC_OK();
|
||||
}
|
||||
if (NS_CP_REJECTED(decision)) {
|
||||
aResolve(NS_BINDING_FAILED);
|
||||
} else {
|
||||
aResolve(NS_OK);
|
||||
}
|
||||
cancelCode);
|
||||
aResolve(Tuple<const nsresult&, const Maybe<nsresult>&>(rv, cancelCode));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -240,8 +240,8 @@ void DocumentChannelParent::FinishReplacementChannelSetup(bool aSucceeded) {
|
||||
newChannel->Cancel(NS_BINDING_ABORTED);
|
||||
}
|
||||
}
|
||||
// Release all previously registered channels, they are no longer needed to be
|
||||
// kept in the registrar from this moment.
|
||||
// Release all previously registered channels, they are no longer needed to
|
||||
// be kept in the registrar from this moment.
|
||||
registrar->DeregisterChannels(mRedirectChannelId);
|
||||
|
||||
mRedirectChannelId = 0;
|
||||
@ -809,11 +809,11 @@ DocumentChannelParent::AsyncOnChannelRedirect(
|
||||
nsCOMPtr<nsIChannel> oldChannel(aOldChannel);
|
||||
SendConfirmRedirect(newUri)->Then(
|
||||
GetCurrentThreadSerialEventTarget(), __func__,
|
||||
[callback, oldChannel](nsresult aRv) {
|
||||
if (NS_FAILED(aRv)) {
|
||||
oldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
|
||||
[callback, oldChannel](const Tuple<nsresult, Maybe<nsresult>>& aResult) {
|
||||
if (Get<1>(aResult)) {
|
||||
oldChannel->Cancel(*Get<1>(aResult));
|
||||
}
|
||||
callback->OnRedirectVerifyCallback(aRv);
|
||||
callback->OnRedirectVerifyCallback(Get<0>(aResult));
|
||||
},
|
||||
[callback, oldChannel](const mozilla::ipc::ResponseRejectReason) {
|
||||
oldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
|
||||
|
@ -75,7 +75,7 @@ child:
|
||||
uint32_t? aContentDisposition,
|
||||
nsString? aContentDispositionFilename) returns(nsresult rv);
|
||||
|
||||
async ConfirmRedirect(nsIURI aNewURI) returns(nsresult rv);
|
||||
async ConfirmRedirect(nsIURI aNewURI) returns(nsresult rv, nsresult? cancelCode);
|
||||
|
||||
// Tell child to delete channel (all IPDL deletes must be done from child to
|
||||
// avoid races: see bug 591708).
|
||||
|
Loading…
Reference in New Issue
Block a user