tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit c41e8cbc9278967392559e42dce29626c0173c64
parent 4f8dd6362437a8db3a80452c9d333c1fd5e1ae20
Author: Tom Ritter <tom@mozilla.com>
Date:   Fri,  7 Nov 2025 16:34:27 +0000

Bug 1994841: Add an option to JSContext to disable filename validation, and propagate it to CompileOptions r=necko-reviewers,spidermonkey-reviewers,arai

Differential Revision: https://phabricator.services.mozilla.com/D269084

Diffstat:
Mjs/public/ContextOptions.h | 20+++++++++++++++++++-
Mjs/src/jsapi.cpp | 4++++
Mnetwerk/base/ProxyAutoConfig.cpp | 9++++++++-
3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/js/public/ContextOptions.h b/js/public/ContextOptions.h @@ -29,6 +29,7 @@ class JS_PUBLIC_API ContextOptions { testWasmAwaitTier2_(false), disableIon_(false), disableEvalSecurityChecks_(false), + disableFilenameSecurityChecks_(false), asyncStack_(true), asyncStackCaptureDebuggeeOnly_(false), throwOnDebuggeeWouldRun_(true), @@ -105,6 +106,9 @@ class JS_PUBLIC_API ContextOptions { return *this; } + // These next two checks are needed for PAC Scripts: we cannot enforce + // restrictions on them because they are user provided. + // Override to allow disabling the eval restriction security checks for // this context. bool disableEvalSecurityChecks() const { return disableEvalSecurityChecks_; } @@ -113,6 +117,19 @@ class JS_PUBLIC_API ContextOptions { return *this; } + // Override to allow disabling the filename security checks (checks that + // ensure the script doesn't come from the web) for this context. There is a + // lower-level flag for this same check in CompileOptions which will be set by + // this flag; this is needed here to propagate the flag down into eval + // contexts + bool disableFilenameSecurityChecks() const { + return disableFilenameSecurityChecks_; + } + ContextOptions& setDisableFilenameSecurityChecks() { + disableFilenameSecurityChecks_ = true; + return *this; + } + bool asyncStack() const { return asyncStack_; } ContextOptions& setAsyncStack(bool flag) { asyncStack_ = flag; @@ -172,9 +189,10 @@ class JS_PUBLIC_API ContextOptions { // JIT options. bool disableIon_ : 1; - bool disableEvalSecurityChecks_ : 1; // Runtime options. + bool disableEvalSecurityChecks_ : 1; + bool disableFilenameSecurityChecks_ : 1; bool asyncStack_ : 1; bool asyncStackCaptureDebuggeeOnly_ : 1; bool throwOnDebuggeeWouldRun_ : 1; diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp @@ -2637,6 +2637,10 @@ JS::CompileOptions::CompileOptions(JSContext* cx) { alwaysUseFdlibm_ = realm->creationOptions().alwaysUseFdlibm(); discardSource = realm->behaviors().discardSource(); } + + if (cx->options().disableFilenameSecurityChecks()) { + skipFilenameValidation_ = true; + } } JS::InstantiateOptions::InstantiateOptions() { diff --git a/netwerk/base/ProxyAutoConfig.cpp b/netwerk/base/ProxyAutoConfig.cpp @@ -392,7 +392,14 @@ class JSContextWrapper { JSContext* cx = JS_NewContext(JS::DefaultHeapMaxBytes + aExtraHeapSize); if (NS_WARN_IF(!cx)) return nullptr; - JS::ContextOptionsRef(cx).setDisableIon().setDisableEvalSecurityChecks(); + // PAC scripts are user-provided scripts that run in the parent process. + // Disable Ion because we don't require it and it reduces attack surface. + // Disable security checks because we cannot enforce restrictions on these + // scripts. + JS::ContextOptionsRef(cx) + .setDisableIon() + .setDisableEvalSecurityChecks() + .setDisableFilenameSecurityChecks(); JSContextWrapper* entry = new JSContextWrapper(cx); if (NS_FAILED(entry->Init())) {