Firefox · DOM
CVE-2026-16379
Logic Error in DOM
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
mWasFileChanneluriloader/exthandler/ExternalHelperAppParent.cpp |
modified |
Files Changed
dom/ipc/ContentParent.cppdom/ipc/ContentParent.hdom/ipc/PContent.ipdluriloader/exthandler/ExternalHelperAppParent.cppuriloader/exthandler/ExternalHelperAppParent.huriloader/exthandler/nsExternalHelperAppService.cpp
Patch
diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
index 3538da8e512..c9af3b237e2 100644
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -61,6 +61,7 @@
#include "mozilla/ScriptPreloader.h"
#include "mozilla/Services.h"
#include "mozilla/Sprintf.h"
+#include "mozilla/StaticPrefs_browser.h"
#include "mozilla/StaticPrefs_dom.h"
#include "mozilla/StaticPrefs_fission.h"
#include "mozilla/StaticPrefs_media.h"
@@ -4710,11 +4711,11 @@ ContentParent::AllocPExternalHelperAppParent(
const nsACString& aMimeContentType, const nsACString& aContentDisposition,
const uint32_t& aContentDispositionHint,
const nsAString& aContentDispositionFilename, const bool& aForceSave,
- const int64_t& aContentLength, const bool& aWasFileChannel,
- nsIURI* aReferrer, const MaybeDiscarded<BrowsingContext>& aContext) {
+ const int64_t& aContentLength, nsIURI* aReferrer,
+ const MaybeDiscarded<BrowsingContext>& aContext) {
RefPtr<ExternalHelperAppParent> parent = new ExternalHelperAppParent(
- uri, aContentLength, aWasFileChannel, aContentDisposition,
- aContentDispositionHint, aContentDispositionFilename);
+ uri, aContentLength, aContentDisposition, aContentDispositionHint,
+ aContentDispositionFilename);
return parent.forget();
}
@@ -4724,8 +4725,20 @@ mozilla::ipc::IPCResult ContentParent::RecvPExternalHelperAppConstructor(
const nsACString& aContentDisposition,
const uint32_t& aContentDispositionHint,
const nsAString& aContentDispositionFilename, const bool& aForceSave,
- const int64_t& aContentLength, const bool& aWasFileChannel,
- nsIURI* aReferrer, const MaybeDiscarded<BrowsingContext>& aContext) {
+ const int64_t& aContentLength, nsIURI* aReferrer,
+ const MaybeDiscarded<BrowsingContext>& aContext) {
+ // A content process must never be able to drive a native helper-app launch
+ // of a local file it chose: that decision has to be bound to a channel the
+ // process was actually allowed to open. A file:// URI can only be loaded in
+ // a file content process (mirrors ValidatePrincipalCouldPotentiallyBeLoadedBy
+ // and the sandboxing policy enforced in ProcessIsolation), so reject a
+ // file:// URI coming from any other process.
+ if (uri && uri->SchemeIs("file") &&
+ StaticPrefs::browser_tabs_remote_separateFileUriProcess() &&
+ GetRemoteType() != FILE_REMOTE_TYPE) {
+ return IPC_FAIL(this, "Non-file process sent a file:// URI.");
+ }
+
BrowsingContext* context = aContext.IsDiscarded() ? nullptr : aContext.get();
if (!static_cast<ExternalHelperAppParent*>(actor)->Init(
loadInfoArgs, aMimeContentType, aForceSave, aReferrer, context)) {
diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h
index 6a0559b9e3c..ecbd84b707d 100644
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -947,8 +947,8 @@ class ContentParent final : public PContentParent,
const nsACString& aMimeContentType, const nsACString& aContentDisposition,
const uint32_t& aContentDispositionHint,
const nsAString& aContentDispositionFilename, const bool& aForceSave,
- const int64_t& aContentLength, const bool& aWasFileChannel,
- nsIURI* aReferrer, const MaybeDiscarded<BrowsingContext>& aContext);
+ const int64_t& aContentLength, nsIURI* aReferrer,
+ const MaybeDiscarded<BrowsingContext>& aContext);
mozilla::ipc::IPCResult RecvPExternalHelperAppConstructor(
PExternalHelperAppParent* actor, nsIURI* uri,
@@ -956,8 +956,7 @@ class ContentParent final : public PContentParent,
const nsACString& aContentDisposition,
const uint32_t& aContentDispositionHint,
const nsAString& aContentDispositionFilename, const bool& aForceSave,
- const int64_t& aContentLength, const bool& aWasFileChannel,
- nsIURI* aReferrer,
+ const int64_t& aContentLength, nsIURI* aReferrer,
const MaybeDiscarded<BrowsingContext>& aContext) override;
already_AddRefed<PHandlerServiceParent> AllocPHandlerServiceParent();
diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl
index ebcde0b2b2c..c298d3e834e 100644
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -1240,7 +1240,6 @@ parent:
nsString aContentDispositionFilename,
bool aForceSave,
int64_t aContentLength,
- bool aWasFileChannel,
nullable nsIURI aReferrer,
MaybeDiscardedBrowsingContext aContext);
diff --git a/uriloader/exthandler/ExternalHelperAppParent.cpp b/uriloader/exthandler/ExternalHelperAppParent.cpp
index 912b4f4a27b..376f24c68fb 100644
--- a/uriloader/exthandler/ExternalHelperAppParent.cpp
+++ b/uriloader/exthandler/ExternalHelperAppParent.cpp
@@ -31,7 +31,7 @@ NS_IMPL_ISUPPORTS_INHERITED(ExternalHelperAppParent, nsHashPropertyBag,
nsIStreamListener, nsIExternalHelperAppParent)
ExternalHelperAppParent::ExternalHelperAppParent(
- nsIURI* uri, const int64_t& aContentLength, const bool& aWasFileChannel,
+ nsIURI* uri, const int64_t& aContentLength,
const nsACString& aContentDispositionHeader,
const uint32_t& aContentDispositionHint,
const nsAString& aContentDispositionFilename)
@@ -42,7 +42,9 @@ ExternalHelperAppParent::ExternalHelperAppParent(
mStatus(NS_OK),
mCanceled(false),
mContentLength(aContentLength),
- mWasFileChannel(aWasFileChannel) {
+ // Never trust a child-supplied flag for the native helper-launch
+ // decision: derive it from the actual URI the parent will operate on.
+ mWasFileChannel(uri && uri->SchemeIs("file")) {
mContentDispositionHeader = aContentDispositionHeader;
if (!mContentDispositionHeader.IsEmpty()) {
NS_GetFilenameFromDisposition(mContentDispositionFilename,
diff --git a/uriloader/exthandler/ExternalHelperAppParent.h b/uriloader/exthandler/ExternalHelperAppParent.h
index d47a3f7bf27..b726be721f5 100644
--- a/uriloader/exthandler/ExternalHelperAppParent.h
+++ b/uriloader/exthandler/ExternalHelperAppParent.h
@@ -71,7 +71,6 @@ class ExternalHelperAppParent
bool WasFileChannel() override { return mWasFileChannel; }
ExternalHelperAppParent(nsIURI* uri, const int64_t& contentLength,
- const bool& wasFileChannel,
const nsACString& aContentDispositionHeader,
const uint32_t& aContentDispositionHint,
const nsAString& aContentDispositionFilename);
diff --git a/uriloader/exthandler/nsExternalHelperAppService.cpp b/uriloader/exthandler/nsExternalHelperAppService.cpp
index 862b6cba4ee..b39823443c8 100644
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -720,7 +720,6 @@ nsresult nsExternalHelperAppService::DoContentContentProcessHelper(
nsCString disp;
nsCOMPtr<nsIURI> uri;
int64_t contentLength = -1;
- bool wasFileChannel = false;
uint32_t contentDisposition = -1;
nsAutoString fileName;
nsCOMPtr<nsILoadInfo> loadInfo;
@@ -732,9 +731,6 @@ nsresult nsExternalHelperAppService::DoContentContentProcessHelper(
aChannel->GetContentDispositionHeader(disp);
loadInfo = aChannel->LoadInfo();
- nsCOMPtr<nsIFileChannel> fileChan(do_QueryInterface(aChannel));
- wasFileChannel = fileChan != nullptr;
-
nsCOMPtr<nsIURI> referrer;
NS_GetReferrerFromChannel(aChannel, getter_AddRefs(referrer));
@@ -748,8 +744,8 @@ nsresult nsExternalHelperAppService::DoContentContentProcessHelper(
RefPtr childListener = MakeRefPtr<ExternalHelperAppChild>();
MOZ_ALWAYS_TRUE(child->SendPExternalHelperAppConstructor(
childListener, uri, loadInfoArgs, nsCString(aMimeContentType), disp,
- contentDisposition, fileName, aForceSave, contentLength, wasFileChannel,
- referrer, aContentContext));
+ contentDisposition, fileName, aForceSave, contentLength, referrer,
+ aContentContext));
NS_ADDREF(*aStreamListener = childListener);
Loading diff…
References
On This Page