Bug 1626404: Part 1 - Move IsSandboxedFrom to BrowsingContext. r=nika CLOSED TREE
Differential Revision: https://phabricator.services.mozilla.com/D69417
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
#include "nsGlobalWindowOuter.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "nsScriptError.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "xpcprivate.h"
|
||||
@@ -889,6 +890,61 @@ bool BrowsingContext::CanAccess(BrowsingContext* aTarget,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BrowsingContext::IsSandboxedFrom(BrowsingContext* aTarget) {
|
||||
// If no target then not sandboxed.
|
||||
if (!aTarget) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We cannot be sandboxed from ourselves.
|
||||
if (aTarget == this) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Default the sandbox flags to our flags, so that if we can't retrieve the
|
||||
// active document, we will still enforce our own.
|
||||
uint32_t sandboxFlags = GetSandboxFlags();
|
||||
if (mDocShell) {
|
||||
if (RefPtr<Document> doc = mDocShell->GetExtantDocument()) {
|
||||
sandboxFlags = doc->GetSandboxFlags();
|
||||
}
|
||||
}
|
||||
|
||||
// If no flags, we are not sandboxed at all.
|
||||
if (!sandboxFlags) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If aTarget has an ancestor, it is not top level.
|
||||
if (RefPtr<BrowsingContext> ancestorOfTarget = aTarget->GetParent()) {
|
||||
do {
|
||||
// We are not sandboxed if we are an ancestor of target.
|
||||
if (ancestorOfTarget == this) {
|
||||
return false;
|
||||
}
|
||||
ancestorOfTarget = ancestorOfTarget->GetParent();
|
||||
} while (ancestorOfTarget);
|
||||
|
||||
// Otherwise, we are sandboxed from aTarget.
|
||||
return true;
|
||||
}
|
||||
|
||||
// aTarget is top level, are we the "one permitted sandboxed
|
||||
// navigator", i.e. did we open aTarget?
|
||||
if (aTarget->GetOnePermittedSandboxedNavigatorId() == Id()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If SANDBOXED_TOPLEVEL_NAVIGATION flag is not on, we are not sandboxed
|
||||
// from our top.
|
||||
if (!(sandboxFlags & SANDBOXED_TOPLEVEL_NAVIGATION) && aTarget == Top()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, we are sandboxed from aTarget.
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<SessionStorageManager> BrowsingContext::GetSessionStorageManager() {
|
||||
RefPtr<SessionStorageManager>& manager = Top()->mSessionStorageManager;
|
||||
if (!manager) {
|
||||
|
||||
@@ -538,6 +538,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
||||
// Performs access control to check that 'this' can access 'aTarget'.
|
||||
bool CanAccess(BrowsingContext* aTarget, bool aConsiderOpener = true);
|
||||
|
||||
bool IsSandboxedFrom(BrowsingContext* aTarget);
|
||||
|
||||
// The runnable will be called once there is idle time, or the top level
|
||||
// page has been loaded or if a timeout has fired.
|
||||
// Must be called only on the top level BrowsingContext.
|
||||
|
||||
@@ -2731,66 +2731,6 @@ nsDocShell::GetSameTypeRootTreeItemIgnoreBrowserBoundaries(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool nsDocShell::IsSandboxedFrom(BrowsingContext* aTargetBC) {
|
||||
// If no target then not sandboxed.
|
||||
if (!aTargetBC) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We cannot be sandboxed from ourselves.
|
||||
if (aTargetBC == mBrowsingContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Default the sandbox flags to our flags, so that if we can't retrieve the
|
||||
// active document, we will still enforce our own.
|
||||
uint32_t sandboxFlags = mBrowsingContext->GetSandboxFlags();
|
||||
if (mContentViewer) {
|
||||
RefPtr<Document> doc = mContentViewer->GetDocument();
|
||||
if (doc) {
|
||||
sandboxFlags = doc->GetSandboxFlags();
|
||||
}
|
||||
}
|
||||
|
||||
// If no flags, we are not sandboxed at all.
|
||||
if (!sandboxFlags) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If aTargetBC has an ancestor, it is not top level.
|
||||
RefPtr<BrowsingContext> ancestorOfTarget(aTargetBC->GetParent());
|
||||
if (ancestorOfTarget) {
|
||||
do {
|
||||
// We are not sandboxed if we are an ancestor of target.
|
||||
if (ancestorOfTarget == mBrowsingContext) {
|
||||
return false;
|
||||
}
|
||||
ancestorOfTarget = ancestorOfTarget->GetParent();
|
||||
} while (ancestorOfTarget);
|
||||
|
||||
// Otherwise, we are sandboxed from aTargetBC.
|
||||
return true;
|
||||
}
|
||||
|
||||
// aTargetBC is top level, are we the "one permitted sandboxed
|
||||
// navigator", i.e. did we open aTargetBC?
|
||||
RefPtr<BrowsingContext> permittedNavigator(
|
||||
aTargetBC->GetOnePermittedSandboxedNavigator());
|
||||
if (permittedNavigator == mBrowsingContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If SANDBOXED_TOPLEVEL_NAVIGATION flag is not on, we are not sandboxed
|
||||
// from our top.
|
||||
if (!(sandboxFlags & SANDBOXED_TOPLEVEL_NAVIGATION) &&
|
||||
aTargetBC == mBrowsingContext->Top()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, we are sandboxed from aTargetBC.
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner) {
|
||||
NS_ENSURE_ARG_POINTER(aTreeOwner);
|
||||
@@ -3199,6 +3139,10 @@ Document* nsDocShell::GetDocument() {
|
||||
return mContentViewer->GetDocument();
|
||||
}
|
||||
|
||||
Document* nsDocShell::GetExtantDocument() {
|
||||
return mContentViewer ? mContentViewer->GetDocument() : nullptr;
|
||||
}
|
||||
|
||||
nsPIDOMWindowOuter* nsDocShell::GetWindow() {
|
||||
if (NS_FAILED(EnsureScriptEnvironment())) {
|
||||
return nullptr;
|
||||
@@ -8787,7 +8731,8 @@ 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.
|
||||
if (aLoadState->SourceDocShell() &&
|
||||
aLoadState->SourceDocShell()->IsSandboxedFrom(mBrowsingContext)) {
|
||||
aLoadState->SourceDocShell()->GetBrowsingContext()->IsSandboxedFrom(
|
||||
mBrowsingContext)) {
|
||||
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||
}
|
||||
|
||||
|
||||
@@ -737,12 +737,6 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
*/
|
||||
readonly attribute bool asyncPanZoomEnabled;
|
||||
|
||||
/**
|
||||
* Returns true if we are sandboxed from aTargetDocShell.
|
||||
* aTargetDocShell - the browsing context we are attempting to navigate.
|
||||
*/
|
||||
[noscript,notxpcom,nostdcall] bool isSandboxedFrom(in BrowsingContext aTargetBC);
|
||||
|
||||
/**
|
||||
* This member variable determines whether a document has Mixed Active Content that
|
||||
* was initially blocked from loading, but the user has choosen to override the
|
||||
@@ -881,6 +875,8 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
*/
|
||||
[noscript,notxpcom,nostdcall] nsIScriptGlobalObject GetScriptGlobalObject();
|
||||
|
||||
[noscript,notxpcom,nostdcall] Document getExtantDocument();
|
||||
|
||||
/**
|
||||
* If deviceSizeIsPageSize is set to true, device-width/height media queries
|
||||
* will be calculated from the page size, not the device size.
|
||||
|
||||
@@ -653,6 +653,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
|
||||
|
||||
RefPtr<BrowsingContext> parentBC(
|
||||
parentWindow ? parentWindow->GetBrowsingContext() : nullptr);
|
||||
nsCOMPtr<nsIDocShell> parentDocShell(parentBC ? parentBC->GetDocShell()
|
||||
: nullptr);
|
||||
|
||||
// Return null for any attempt to trigger a load from a discarded browsing
|
||||
// context. The spec is non-normative, and doesn't specify what should happen
|
||||
@@ -673,15 +675,9 @@ nsresult nsWindowWatcher::OpenWindowInternal(
|
||||
// Do sandbox checks here, instead of waiting until nsIDocShell::LoadURI.
|
||||
// The state of the window can change before this call and if we are blocked
|
||||
// because of sandboxing, we wouldn't want that to happen.
|
||||
nsCOMPtr<nsIDocShell> parentDocShell;
|
||||
if (parentWindow) {
|
||||
parentDocShell = parentWindow->GetDocShell();
|
||||
if (parentDocShell) {
|
||||
if (parentDocShell->IsSandboxedFrom(newBC)) {
|
||||
if (parentBC && parentBC->IsSandboxedFrom(newBC)) {
|
||||
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no extant window? make a new one.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user