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 "nsGlobalWindowOuter.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsSandboxFlags.h"
|
||||||
#include "nsScriptError.h"
|
#include "nsScriptError.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "xpcprivate.h"
|
#include "xpcprivate.h"
|
||||||
@@ -889,6 +890,61 @@ bool BrowsingContext::CanAccess(BrowsingContext* aTarget,
|
|||||||
return false;
|
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> BrowsingContext::GetSessionStorageManager() {
|
||||||
RefPtr<SessionStorageManager>& manager = Top()->mSessionStorageManager;
|
RefPtr<SessionStorageManager>& manager = Top()->mSessionStorageManager;
|
||||||
if (!manager) {
|
if (!manager) {
|
||||||
|
|||||||
@@ -538,6 +538,8 @@ class BrowsingContext : public nsILoadContext, public nsWrapperCache {
|
|||||||
// Performs access control to check that 'this' can access 'aTarget'.
|
// Performs access control to check that 'this' can access 'aTarget'.
|
||||||
bool CanAccess(BrowsingContext* aTarget, bool aConsiderOpener = true);
|
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
|
// The runnable will be called once there is idle time, or the top level
|
||||||
// page has been loaded or if a timeout has fired.
|
// page has been loaded or if a timeout has fired.
|
||||||
// Must be called only on the top level BrowsingContext.
|
// Must be called only on the top level BrowsingContext.
|
||||||
|
|||||||
@@ -2731,66 +2731,6 @@ nsDocShell::GetSameTypeRootTreeItemIgnoreBrowserBoundaries(
|
|||||||
return NS_OK;
|
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
|
NS_IMETHODIMP
|
||||||
nsDocShell::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner) {
|
nsDocShell::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner) {
|
||||||
NS_ENSURE_ARG_POINTER(aTreeOwner);
|
NS_ENSURE_ARG_POINTER(aTreeOwner);
|
||||||
@@ -3199,6 +3139,10 @@ Document* nsDocShell::GetDocument() {
|
|||||||
return mContentViewer->GetDocument();
|
return mContentViewer->GetDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Document* nsDocShell::GetExtantDocument() {
|
||||||
|
return mContentViewer ? mContentViewer->GetDocument() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
nsPIDOMWindowOuter* nsDocShell::GetWindow() {
|
nsPIDOMWindowOuter* nsDocShell::GetWindow() {
|
||||||
if (NS_FAILED(EnsureScriptEnvironment())) {
|
if (NS_FAILED(EnsureScriptEnvironment())) {
|
||||||
return nullptr;
|
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
|
// 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.
|
// from it as the result of an iframe or CSP sandbox.
|
||||||
if (aLoadState->SourceDocShell() &&
|
if (aLoadState->SourceDocShell() &&
|
||||||
aLoadState->SourceDocShell()->IsSandboxedFrom(mBrowsingContext)) {
|
aLoadState->SourceDocShell()->GetBrowsingContext()->IsSandboxedFrom(
|
||||||
|
mBrowsingContext)) {
|
||||||
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -737,12 +737,6 @@ interface nsIDocShell : nsIDocShellTreeItem
|
|||||||
*/
|
*/
|
||||||
readonly attribute bool asyncPanZoomEnabled;
|
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
|
* 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
|
* 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] nsIScriptGlobalObject GetScriptGlobalObject();
|
||||||
|
|
||||||
|
[noscript,notxpcom,nostdcall] Document getExtantDocument();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If deviceSizeIsPageSize is set to true, device-width/height media queries
|
* If deviceSizeIsPageSize is set to true, device-width/height media queries
|
||||||
* will be calculated from the page size, not the device size.
|
* will be calculated from the page size, not the device size.
|
||||||
|
|||||||
@@ -653,6 +653,8 @@ nsresult nsWindowWatcher::OpenWindowInternal(
|
|||||||
|
|
||||||
RefPtr<BrowsingContext> parentBC(
|
RefPtr<BrowsingContext> parentBC(
|
||||||
parentWindow ? parentWindow->GetBrowsingContext() : nullptr);
|
parentWindow ? parentWindow->GetBrowsingContext() : nullptr);
|
||||||
|
nsCOMPtr<nsIDocShell> parentDocShell(parentBC ? parentBC->GetDocShell()
|
||||||
|
: nullptr);
|
||||||
|
|
||||||
// Return null for any attempt to trigger a load from a discarded browsing
|
// 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
|
// 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.
|
// 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
|
// 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.
|
// because of sandboxing, we wouldn't want that to happen.
|
||||||
nsCOMPtr<nsIDocShell> parentDocShell;
|
if (parentBC && parentBC->IsSandboxedFrom(newBC)) {
|
||||||
if (parentWindow) {
|
|
||||||
parentDocShell = parentWindow->GetDocShell();
|
|
||||||
if (parentDocShell) {
|
|
||||||
if (parentDocShell->IsSandboxedFrom(newBC)) {
|
|
||||||
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// no extant window? make a new one.
|
// no extant window? make a new one.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user