Firefox · DOM
CVE-2026-109734
Logic Error in DOM
Overview
Moderate
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Files Changed
dom/jsurl/nsJSProtocolHandler.cppnetwerk/base/LoadInfo.hnetwerk/base/TRRLoadInfo.cppnetwerk/base/nsILoadInfo.idltesting/web-platform/meta/content-security-policy/inheritance/inheritance-from-initiator.sub.html.ini
Patch
diff --git a/dom/jsurl/nsJSProtocolHandler.cpp b/dom/jsurl/nsJSProtocolHandler.cpp
index d9e9781a478..23a129179e5 100644
--- a/dom/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/jsurl/nsJSProtocolHandler.cpp
@@ -337,6 +337,20 @@ nsresult JSURLInputStream::EvaluateScript(
}
}
+ // https://html.spec.whatwg.org/#evaluate-a-javascript:-url
+ // Step 12. Let policyContainer be targetNavigable's active document's
+ // policy container.
+ //
+ // A document created from the string this script evaluates to inherits the
+ // target document's policy container, not the initiating document's one
+ // that docshell stored on the loadinfo for the check above. Store an actual
+ // copy so that modifications done by the new document (such as its meta
+ // CSP) don't propagate back into the target document.
+ RefPtr policyContainerToInherit = mozilla::MakeRefPtr<PolicyContainer>();
+ policyContainerToInherit->InitFromOther(
+ PolicyContainer::Cast(targetDoc->GetPolicyContainer()));
+ loadInfo->SetPolicyContainerToInherit(policyContainerToInherit);
+
// If the original channel's nsILoadInfo has a PermissionsPolicyInfo,
// copy it to the new channel.
if (nsCOMPtr<nsIChannel> originalChannel = targetDoc->GetChannel()) {
diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h
index c078b935277..a6a44ac715a 100644
--- a/netwerk/base/LoadInfo.h
+++ b/netwerk/base/LoadInfo.h
@@ -344,31 +344,6 @@ class LoadInfo final : public nsILoadInfo {
dom::ReferrerPolicy GetFrameReferrerPolicySnapshot() const;
void SetFrameReferrerPolicySnapshot(dom::ReferrerPolicy aPolicy);
- // Hands off from the cspToInherit functionality!
- //
- // For navigations, GetCSPToInherit returns what the spec calls the
- // "request's client's global object's CSP list", or more precisely
- // a snapshot of it taken when the navigation starts. For
- // navigations that need to inherit their CSP, this is the right CSP
- // to use for the new document. We need a way to transfer the CSP
- // from the docshell (where the navigation starts) to the point where
- // the new document is created and decides whether to inherit its
- // CSP, and this is the mechanism we use for that.
- //
- // For example:
- // A document with a CSP triggers a new top-level data: URI load.
- // We pass the CSP of the document that triggered the load all the
- // way to docshell. Within docshell we call SetCSPToInherit() on the
- // loadinfo. Within Document::InitCSP() we check if the newly created
- // document needs to inherit the CSP. If so, we call
- // GetCSPToInherit() and set the inherited CSP as the CSP for the new
- // document. Please note that any additonal Meta CSP in that document
- // will be merged into that CSP. Any subresource loads within that
- // document subesquently will receive the correct CSP by querying
- // loadinfo->GetCsp() from that point on.
- void SetPolicyContainerToInherit(
- nsIPolicyContainer* aPolicyContainerToInherit);
-
bool HasIsThirdPartyContextToTopWindowSet() {
return mIsThirdPartyContextToTopWindow.isSome();
}
diff --git a/netwerk/base/TRRLoadInfo.cpp b/netwerk/base/TRRLoadInfo.cpp
index 0d8b34cfb93..0cba5455007 100644
--- a/netwerk/base/TRRLoadInfo.cpp
+++ b/netwerk/base/TRRLoadInfo.cpp
@@ -497,6 +497,9 @@ TRRLoadInfo::GetPolicyContainerToInherit() {
return nullptr;
}
+void TRRLoadInfo::SetPolicyContainerToInherit(
+ nsIPolicyContainer* aPolicyContainerToInherit) {}
+
Maybe<PermissionsPolicyInfo> TRRLoadInfo::GetContainerPermissionsPolicyInfo() {
return Nothing();
}
diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl
index 3279d195d47..a3e7384515b 100644
--- a/netwerk/base/nsILoadInfo.idl
+++ b/netwerk/base/nsILoadInfo.idl
@@ -1474,7 +1474,36 @@ interface nsILoadInfo : nsISupports
[notxpcom,nostdcall] CSPRef GetPreloadCsp();
[notxpcom,nostdcall] PolicyContainerRef GetPolicyContainer();
+
+ /**
+ * Hands off from the policyContainerToInherit functionality!
+ *
+ * For navigations, GetPolicyContainerToInherit returns what the spec calls
+ * the "request's client's global object's CSP list", or more precisely a
+ * snapshot of it taken when the navigation starts. For navigations that
+ * need to inherit their CSP, this is the right CSP to use for the new
+ * document. We need a way to transfer the CSP from the docshell (where the
+ * navigation starts) to the point where the new document is created and
+ * decides whether to inherit its CSP, and this is the mechanism we use for
+ * that.
+ *
+ * For example:
+ * A document with a CSP triggers a new top-level data: URI load.
+ * We pass the CSP of the document that triggered the load all the
+ * way to docshell. Within docshell we call SetPolicyContainerToInherit() on
+ * the loadinfo. Within Document::InitPolicyContainer() we check if the newly
+ * created document needs to inherit the policy container. If so, we call
+ * GetPolicyContainerToInherit(). Please note that any additonal Meta CSP in
+ * that document will be merged into that CSP. Any subresource loads within
+ * that document subesquently will receive the correct CSP by querying
+ * loadinfo->GetPolicyContainer() from that point on.
+ *
+ * javascript: URLs are the exception: the document they create inherits the
+ * policy container of the document it replaces, so nsJSThunk overrides the
+ * value docshell set here once it knows that document.
+ */
[notxpcom,nostdcall] PolicyContainerRef GetPolicyContainerToInherit();
+ [notxpcom,nostdcall] void SetPolicyContainerToInherit(in nsIPolicyContainer aPolicyContainerToInherit);
/**
* The possibly cross-origin container permissions policy required to
diff --git a/testing/web-platform/meta/content-security-policy/inheritance/inheritance-from-initiator.sub.html.ini b/testing/web-platform/meta/content-security-policy/inheritance/inheritance-from-initiator.sub.html.ini
index e3e7fd6064b..826273ffe5b 100644
--- a/testing/web-platform/meta/content-security-policy/inheritance/inheritance-from-initiator.sub.html.ini
+++ b/testing/web-platform/meta/content-security-policy/inheritance/inheritance-from-initiator.sub.html.ini
@@ -12,28 +12,3 @@
[blob: Click on anchor inherits from owner of the anchor (apart from javascript:, which keeps target policies, and blob:, which always inherits from creator).]
expected: FAIL
-
-[inheritance-from-initiator.sub.html?scheme=javascript]
- [javascript: Setting src inherits from parent (apart from javascript:, which keeps target policies).]
- expected: FAIL
-
- [javascript: Changing contentWindow.location inherits from who changed it (apart from javascript:, which keeps target policies, and blob:, which always inherits from creator).]
- expected: FAIL
-
- [javascript: Changing contentWindow.location indirectly inherits from who changed it directly (apart from javascript:, which keeps target policies).]
- expected: FAIL
-
- [javascript: window.open() inherits from caller (apart from javascript:, which keeps target policies, and blob:, which always inherits from creator).]
- expected: FAIL
-
- [javascript: Click on anchor inherits from owner of the anchor (apart from javascript:, which keeps target policies, and blob:, which always inherits from creator).]
- expected: FAIL
-
- [javascript: Form submission through submit() inherits from owner of form (apart from javascript:, which keeps target policies).]
- expected: FAIL
-
- [javascript: Form submission through button click inherits from owner of form (apart from javascript:, which keeps target policies).]
- expected: FAIL
-
-
-[inheritance-from-initiator.sub.html?scheme=data]
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/testing/web-platform/meta/content-security-policy/inheritance/inheritance-from-initiator.sub.html.ini b/testing/web-platform/meta/content-security-policy/inheritance/inheritance-from-initiator.sub.html.ini
index e3e7fd6064b..826273ffe5b 100644
--- a/testing/web-platform/meta/content-security-policy/inheritance/inheritance-from-initiator.sub.html.ini
+++ b/testing/web-platform/meta/content-security-policy/inheritance/inheritance-from-initiator.sub.html.ini
@@ -12,28 +12,3 @@
[blob: Click on anchor inherits from owner of the anchor (apart from javascript:, which keeps target policies, and blob:, which always inherits from creator).]
expected: FAIL
-
-[inheritance-from-initiator.sub.html?scheme=javascript]
- [javascript: Setting src inherits from parent (apart from javascript:, which keeps target policies).]
- expected: FAIL
-
- [javascript: Changing contentWindow.location inherits from who changed it (apart from javascript:, which keeps target policies, and blob:, which always inherits from creator).]
- expected: FAIL
-
- [javascript: Changing contentWindow.location indirectly inherits from who changed it directly (apart from javascript:, which keeps target policies).]
- expected: FAIL
-
- [javascript: window.open() inherits from caller (apart from javascript:, which keeps target policies, and blob:, which always inherits from creator).]
- expected: FAIL
-
- [javascript: Click on anchor inherits from owner of the anchor (apart from javascript:, which keeps target policies, and blob:, which always inherits from creator).]
- expected: FAIL
-
- [javascript: Form submission through submit() inherits from owner of form (apart from javascript:, which keeps target policies).]
- expected: FAIL
-
- [javascript: Form submission through button click inherits from owner of form (apart from javascript:, which keeps target policies).]
- expected: FAIL
-
-
-[inheritance-from-initiator.sub.html?scheme=data]
Loading diff…
References
On This Page