commit 88bfdb3cdb7de6ed796b7d0c1d5cea130bcde0fc
parent 2c006c4d18034afc7a6457d29168fcf2a3f63c7d
Author: Simon Farre <simon.farre.cx@gmail.com>
Date: Fri, 9 Jan 2026 13:43:41 +0000
Bug 2009144 - Allow Navigation API to navigate sandboxed frames sometimes r=smaug,farre
Use the correct source document, from which we create source snapshot
params, so that step 6.2 in https://html.spec.whatwg.org/#navigate,
which calls "allowed by sandboxing to navigate" get the correct input.
This makes the two tests referenced in this commit pass.
Differential Revision: https://phabricator.services.mozilla.com/D278268
Diffstat:
3 files changed, 21 insertions(+), 18 deletions(-)
diff --git a/docshell/base/BrowsingContext.cpp b/docshell/base/BrowsingContext.cpp
@@ -1430,6 +1430,7 @@ BrowsingContext* BrowsingContext::FindWithNameInSubtree(
return nullptr;
}
+// https://html.spec.whatwg.org/#allowed-to-navigate
bool BrowsingContext::IsSandboxedFrom(BrowsingContext* aTarget) {
// If no target then not sandboxed.
if (!aTarget) {
@@ -2467,14 +2468,28 @@ void BrowsingContext::Navigate(
loadState->SetLoadType(LOAD_STOP_CONTENT);
}
- // Get the incumbent script's browsing context to set as source.
- nsCOMPtr<nsPIDOMWindowInner> sourceWindow =
- nsContentUtils::IncumbentInnerWindow();
- if (sourceWindow) {
- WindowContext* context = sourceWindow->GetWindowContext();
- loadState->SetSourceBrowsingContext(sourceWindow->GetBrowsingContext());
+ const auto snapShot = [&](auto& source) {
+ loadState->SetSourceBrowsingContext(source->GetBrowsingContext());
+ WindowContext* context = source->GetWindowContext();
loadState->SetHasValidUserGestureActivation(
context && context->HasValidTransientUserGestureActivation());
+ };
+
+ // aSourceDocument is used for snapshot params and "allowed by sandboxing to
+ // navigate" in https://html.spec.whatwg.org/#navigate first step 2 then 6.2.
+ // When snap shotting we read the UA value
+ // https://html.spec.whatwg.org/#snapshotting-source-snapshot-params
+ if (aSourceDocument) {
+ snapShot(aSourceDocument);
+ } else if (nsCOMPtr<nsPIDOMWindowInner> incumbentWindow =
+ nsContentUtils::IncumbentInnerWindow()) {
+ // Get the incumbent script's browsing context to set as source, if no
+ // source document was provided, as a fallback.
+ // TODO: Possibly remove when BrowsingContext::Navigate can get called when
+ // `userInvolvement == "browser UI"` (aSourceDocument will be null then),
+ // because then, snap shot params get default values like has UA = true,
+ // sandbox flags = 0
+ snapShot(incumbentWindow);
}
loadState->SetLoadFlags(nsIWebNavigation::LOAD_FLAGS_NONE);
diff --git a/testing/web-platform/meta/navigation-api/navigation-methods/sandboxing-navigate-parent.html.ini b/testing/web-platform/meta/navigation-api/navigation-methods/sandboxing-navigate-parent.html.ini
@@ -1,8 +0,0 @@
-[sandboxing-navigate-parent.html]
- expected:
- if (os == "linux") and debug and not fission: [OK, ERROR]
- if (os == "linux") and not debug and fission: [OK, ERROR]
- if (os == "android") and not debug: [OK, ERROR]
- if os == "win": [OK, ERROR]
- [A sandboxed iframe can use its sibling's navigation object to call navigate(), as long as allow-same-origin is present]
- expected: FAIL
diff --git a/testing/web-platform/meta/navigation-api/navigation-methods/sandboxing-navigate-sibling.html.ini b/testing/web-platform/meta/navigation-api/navigation-methods/sandboxing-navigate-sibling.html.ini
@@ -1,4 +0,0 @@
-[sandboxing-navigate-sibling.html]
- expected: TIMEOUT
- [A sandboxed iframe can use its parent's navigation object to call navigate(), as long as allow-same-origin is present]
- expected: TIMEOUT