Bug 1626404: Part 3 - Do sandbox flag checks at both ends of cross-process loads. r=nika CLOSED TREE

Differential Revision: https://phabricator.services.mozilla.com/D69420

--HG--
extra : source : 1a5a559ec6d509167cb58b40086add58c4d63e10
extra : histedit_source : f7ef5aa0524cbfa413cb85101e2591cbd7c26c46
This commit is contained in:
Kris Maglione 2020-04-04 02:42:39 +00:00
parent 2ee2fd5673
commit ffbbc5ba60
3 changed files with 34 additions and 7 deletions

View File

@ -33,6 +33,7 @@
#include "mozilla/Components.h"
#include "mozilla/HashTable.h"
#include "mozilla/Logging.h"
#include "mozilla/ResultExtensions.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPrefs_page_load.h"
#include "mozilla/StaticPtr.h"
@ -1374,6 +1375,14 @@ void BrowsingContext::Location(JSContext* aCx,
}
}
nsresult BrowsingContext::CheckSandboxFlags(nsDocShellLoadState* aLoadState) {
const auto& sourceBC = aLoadState->SourceBrowsingContext();
if (sourceBC.IsDiscarded() || (sourceBC && sourceBC->IsSandboxedFrom(this))) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
return NS_OK;
}
nsresult BrowsingContext::LoadURI(BrowsingContext* aAccessor,
nsDocShellLoadState* aLoadState,
bool aSetNavigating) {
@ -1389,6 +1398,13 @@ nsresult BrowsingContext::LoadURI(BrowsingContext* aAccessor,
return mDocShell->LoadURI(aLoadState, aSetNavigating);
}
// Note: We do this check both here and in `nsDocShell::InternalLoad`, since
// document-specific sandbox flags are only available in the process
// triggering the load, and we don't want the target process to have to trust
// the triggering process to do the appropriate checks for the
// BrowsingContext's sandbox flags.
MOZ_TRY(CheckSandboxFlags(aLoadState));
if (!aAccessor && XRE_IsParentProcess()) {
if (ContentParent* cp = Canonical()->GetContentParent()) {
Unused << cp->SendLoadURI(this, aLoadState, aSetNavigating);
@ -1444,6 +1460,13 @@ nsresult BrowsingContext::InternalLoad(BrowsingContext* aAccessor,
return rv;
}
// Note: We do this check both here and in `nsDocShell::InternalLoad`, since
// document-specific sandbox flags are only available in the process
// triggering the load, and we don't want the target process to have to trust
// the triggering process to do the appropriate checks for the
// BrowsingContext's sandbox flags.
MOZ_TRY(CheckSandboxFlags(aLoadState));
if (XRE_IsParentProcess()) {
if (ContentParent* cp = Canonical()->GetContentParent()) {
Unused << cp->SendInternalLoad(this, aLoadState, isActive);

View File

@ -266,6 +266,11 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
nsDocShellLoadState* aLoadState,
nsIDocShell** aDocShell, nsIRequest** aRequest);
// If the load state includes a source BrowsingContext has been passed, check
// to see if we are sandboxed from it as the result of an iframe or CSP
// sandbox.
nsresult CheckSandboxFlags(nsDocShellLoadState* aLoadState);
void DisplayLoadError(const nsAString& aURI);
// Determine if the current BrowsingContext was 'cached' by the logic in

View File

@ -8728,13 +8728,12 @@ nsresult nsDocShell::InternalLoad(nsDocShellLoadState* aLoadState,
}
}
// If a source docshell has been passed, check to see if we are sandboxed
// from it as the result of an iframe or CSP sandbox.
const auto& sourceBC = aLoadState->SourceBrowsingContext();
if (sourceBC.IsDiscarded() ||
(sourceBC && sourceBC->IsSandboxedFrom(mBrowsingContext))) {
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
// Note: We do this check both here and in BrowsingContext::
// LoadURI/InternalLoad, since document-specific sandbox flags are only
// available in the process triggering the load, and we don't want the target
// process to have to trust the triggering process to do the appropriate
// checks for the BrowsingContext's sandbox flags.
MOZ_TRY(mBrowsingContext->CheckSandboxFlags(aLoadState));
NS_ENSURE_STATE(!HasUnloadedParent());