Backed out 5 changesets (bug 1583076) for href-location-redirected-blocked.sub.html failures CLOSED TREE

Backed out changeset dd4117098844 (bug 1583076)
Backed out changeset 97bc75b1cfe1 (bug 1583076)
Backed out changeset 084b244a33c0 (bug 1583076)
Backed out changeset 1baaf14e2451 (bug 1583076)
Backed out changeset 56c3918b5c21 (bug 1583076)
This commit is contained in:
Bogdan Tara 2019-09-25 00:53:46 +03:00
parent 266236e809
commit f1b65b22c7
7 changed files with 65 additions and 82 deletions

View File

@ -252,6 +252,24 @@ CSPService::AsyncOnChannelRedirect(nsIChannel* oldChannel,
nsCOMPtr<nsILoadInfo> loadInfo = oldChannel->LoadInfo();
// Check CSP navigate-to
// We need to enforce the CSP of the document that initiated the load,
// which is the CSP to inherit.
nsCOMPtr<nsIContentSecurityPolicy> cspToInherit = loadInfo->GetCspToInherit();
if (cspToInherit) {
bool allowsNavigateTo = false;
rv = cspToInherit->GetAllowsNavigateTo(newUri, loadInfo,
true, /* aWasRedirected */
false, /* aEnforceWhitelist */
&allowsNavigateTo);
NS_ENSURE_SUCCESS(rv, rv);
if (!allowsNavigateTo) {
oldChannel->Cancel(NS_ERROR_CSP_NAVIGATE_TO_VIOLATION);
return NS_OK;
}
}
// No need to continue processing if CSP is disabled or if the protocol
// is *not* subject to CSP.
// Please note, the correct way to opt-out of CSP using a custom
@ -278,13 +296,12 @@ CSPService::AsyncOnChannelRedirect(nsIChannel* oldChannel,
return rv;
}
Maybe<nsresult> cancelCode;
rv = ConsultCSPForRedirect(originalUri, newUri, loadInfo, cancelCode);
if (cancelCode) {
oldChannel->Cancel(*cancelCode);
}
if (NS_FAILED(rv)) {
int16_t decision = nsIContentPolicy::ACCEPT;
rv = ConsultCSPForRedirect(originalUri, newUri, loadInfo, &decision);
if (NS_CP_REJECTED(decision)) {
autoCallback.DontCallback();
oldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
return NS_BINDING_FAILED;
}
return rv;
@ -293,34 +310,15 @@ CSPService::AsyncOnChannelRedirect(nsIChannel* oldChannel,
nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
nsIURI* aNewURI,
nsILoadInfo* aLoadInfo,
Maybe<nsresult>& aCancelCode) {
// Check CSP navigate-to
// We need to enforce the CSP of the document that initiated the load,
// which is the CSP to inherit.
nsCOMPtr<nsIContentSecurityPolicy> cspToInherit =
aLoadInfo->GetCspToInherit();
if (cspToInherit) {
bool allowsNavigateTo = false;
nsresult rv = cspToInherit->GetAllowsNavigateTo(
aNewURI, aLoadInfo, true, /* aWasRedirected */
false, /* aEnforceWhitelist */
&allowsNavigateTo);
NS_ENSURE_SUCCESS(rv, rv);
if (!allowsNavigateTo) {
aCancelCode = Some(NS_ERROR_CSP_NAVIGATE_TO_VIOLATION);
return NS_OK;
}
}
int16_t* aDecision) {
nsCOMPtr<nsICSPEventListener> cspEventListener;
nsresult rv =
aLoadInfo->GetCspEventListener(getter_AddRefs(cspEventListener));
MOZ_ALWAYS_SUCCEEDS(rv);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString cspNonce;
rv = aLoadInfo->GetCspNonce(cspNonce);
MOZ_ALWAYS_SUCCEEDS(rv);
NS_ENSURE_SUCCESS(rv, rv);
nsContentPolicyType policyType = aLoadInfo->InternalContentPolicyType();
bool isPreload = nsContentUtils::IsPreloadType(policyType);
@ -332,7 +330,6 @@ 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) {
@ -349,13 +346,12 @@ nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
aOriginalURI, // Original nsIURI
true, // aSendViolationReports
cspNonce, // nonce
&decision);
aDecision);
// if the preload policy already denied the load, then there
// is no point in checking the real policy
if (NS_CP_REJECTED(decision)) {
aCancelCode = Some(NS_ERROR_DOM_BAD_URI);
return NS_BINDING_FAILED;
if (NS_CP_REJECTED(*aDecision)) {
return NS_OK;
}
}
}
@ -373,11 +369,7 @@ nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
aOriginalURI, // Original nsIURI
true, // aSendViolationReports
cspNonce, // nonce
&decision);
if (NS_CP_REJECTED(decision)) {
aCancelCode = Some(NS_ERROR_DOM_BAD_URI);
return NS_BINDING_FAILED;
}
aDecision);
}
return NS_OK;

View File

@ -34,13 +34,9 @@ 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,
Maybe<nsresult>& aCancelCode);
int16_t* aDecision);
protected:
virtual ~CSPService();

View File

@ -738,8 +738,7 @@ nsresult LoadInfoArgsToLoadInfo(
Maybe<mozilla::ipc::CSPInfo> cspToInheritInfo =
loadInfoArgs.cspToInheritInfo();
if (cspToInheritInfo.isSome()) {
nsCOMPtr<Document> doc = do_QueryInterface(aLoadingContext);
cspToInherit = CSPInfoToCSP(cspToInheritInfo.ref(), doc);
cspToInherit = CSPInfoToCSP(cspToInheritInfo.ref(), nullptr);
}
RefPtr<mozilla::LoadInfo> loadInfo = new mozilla::LoadInfo(

View File

@ -255,8 +255,12 @@ IPCResult DocumentChannelChild::RecvRedirectToRealChannel(
const uint32_t& aRedirectFlags, const Maybe<uint32_t>& aContentDisposition,
const Maybe<nsString>& aContentDispositionFilename,
RedirectToRealChannelResolver&& aResolve) {
nsCOMPtr<nsILoadInfo> originalLoadInfo;
RefPtr<dom::Document> loadingDocument;
mLoadInfo->GetLoadingDocument(getter_AddRefs(loadingDocument));
GetLoadInfo(getter_AddRefs(originalLoadInfo));
if (originalLoadInfo) {
originalLoadInfo->GetLoadingDocument(getter_AddRefs(loadingDocument));
}
nsCOMPtr<nsILoadInfo> loadInfo;
nsresult rv = LoadInfoArgsToLoadInfo(aLoadInfo, loadingDocument,
@ -400,30 +404,30 @@ DocumentChannelChild::OnRedirectVerifyCallback(nsresult aStatusCode) {
}
IPCResult DocumentChannelChild::RecvConfirmRedirect(
const LoadInfoArgs& aLoadInfo, nsIURI* aNewUri,
ConfirmRedirectResolver&& aResolve) {
nsIURI* aNewUri, ConfirmRedirectResolver&& aResolve) {
// This is effectively the same as AsyncOnChannelRedirect, except since we're
// not propagating the redirect into this process, we don't have an nsIChannel
// for the redirection and we have to do the checks manually.
// This just checks CSP thus far, hopefully there's not much else needed.
RefPtr<dom::Document> loadingDocument;
mLoadInfo->GetLoadingDocument(getter_AddRefs(loadingDocument));
nsCOMPtr<nsILoadInfo> loadInfo;
MOZ_ALWAYS_SUCCEEDS(LoadInfoArgsToLoadInfo(Some(aLoadInfo), loadingDocument,
getter_AddRefs(loadInfo)));
nsCOMPtr<nsIURI> originalUri;
nsresult rv = GetOriginalURI(getter_AddRefs(originalUri));
if (NS_FAILED(rv)) {
aResolve(Tuple<const nsresult&, const Maybe<nsresult>&>(NS_BINDING_FAILED,
Some(rv)));
aResolve(rv);
return IPC_OK();
}
Maybe<nsresult> cancelCode;
rv = CSPService::ConsultCSPForRedirect(originalUri, aNewUri, loadInfo,
cancelCode);
aResolve(Tuple<const nsresult&, const Maybe<nsresult>&>(rv, cancelCode));
int16_t decision = nsIContentPolicy::ACCEPT;
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);
}
return IPC_OK();
}

View File

@ -82,8 +82,7 @@ class DocumentChannelChild final : public PDocumentChannelChild,
const nsCString& aLists, const nsCString& aFullHash);
mozilla::ipc::IPCResult RecvConfirmRedirect(
const LoadInfoArgs& aLoadInfo, nsIURI* aNewUri,
ConfirmRedirectResolver&& aResolve);
nsIURI* aNewUri, ConfirmRedirectResolver&& aResolve);
void DoFailedAsyncOpen(const nsresult& aStatusCode);

View File

@ -801,31 +801,24 @@ DocumentChannelParent::AsyncOnChannelRedirect(
// process so that it can send events. Send a message to
// our content process to ask CSP if we should allow this
// redirect, and wait for confirmation.
nsCOMPtr<nsILoadInfo> loadInfo = aOldChannel->LoadInfo();
Maybe<LoadInfoArgs> loadInfoArgs;
MOZ_ALWAYS_SUCCEEDS(ipc::LoadInfoToLoadInfoArgs(loadInfo, &loadInfoArgs));
MOZ_ASSERT(loadInfoArgs.isSome());
nsCOMPtr<nsIURI> newUri;
nsresult rv = aNewChannel->GetURI(getter_AddRefs(newUri));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAsyncVerifyRedirectCallback> callback(aCallback);
nsCOMPtr<nsIChannel> oldChannel(aOldChannel);
SendConfirmRedirect(*loadInfoArgs, newUri)
->Then(
GetCurrentThreadSerialEventTarget(), __func__,
[callback,
oldChannel](const Tuple<nsresult, Maybe<nsresult>>& aResult) {
if (Get<1>(aResult)) {
oldChannel->Cancel(*Get<1>(aResult));
}
callback->OnRedirectVerifyCallback(Get<0>(aResult));
},
[callback, oldChannel](const mozilla::ipc::ResponseRejectReason) {
oldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
callback->OnRedirectVerifyCallback(NS_BINDING_ABORTED);
});
SendConfirmRedirect(newUri)->Then(
GetCurrentThreadSerialEventTarget(), __func__,
[callback, oldChannel](nsresult aRv) {
if (NS_FAILED(aRv)) {
oldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
}
callback->OnRedirectVerifyCallback(aRv);
},
[callback, oldChannel](const mozilla::ipc::ResponseRejectReason) {
oldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
callback->OnRedirectVerifyCallback(NS_BINDING_ABORTED);
});
// Clear out our nsIParentChannel functions, since a normal parent
// channel would actually redirect and not have those values on the new one.

View File

@ -75,7 +75,7 @@ child:
uint32_t? aContentDisposition,
nsString? aContentDispositionFilename) returns(nsresult rv);
async ConfirmRedirect(LoadInfoArgs aLoadInfo, nsIURI aNewURI) returns(nsresult rv, nsresult? cancelCode);
async ConfirmRedirect(nsIURI aNewURI) returns(nsresult rv);
// Tell child to delete channel (all IPDL deletes must be done from child to
// avoid races: see bug 591708).