
Pier Angelo Vendrame pushed to branch base-browser-140.3.0esr-15.0-1 at The Tor Project / Applications / Tor Browser Commits: 8765cf34 by Pier Angelo Vendrame at 2025-09-18T17:52:47+02:00 fixup! BB 40925: Implemented the Security Level component BB 44178: Refactor DDG's change of behavior with sec level. With the highest security level, we use the HTML version of DuckDuckGo. We used to change the URL on the fly when doing the search, but this had some problems (different UI, and problems with DDG lite). With this change, we consider the security level when loading the search engine configuration, and change the search URLs at that point. - - - - - 4 changed files: - toolkit/components/search/SearchEngine.sys.mjs - toolkit/components/search/SearchEngineSelector.sys.mjs - toolkit/components/search/SearchService.sys.mjs - toolkit/components/securitylevel/SecurityLevel.sys.mjs Changes: ===================================== toolkit/components/search/SearchEngine.sys.mjs ===================================== @@ -14,7 +14,6 @@ const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { SearchSettings: "moz-src:///toolkit/components/search/SearchSettings.sys.mjs", SearchUtils: "moz-src:///toolkit/components/search/SearchUtils.sys.mjs", - SecurityLevelPrefs: "resource://gre/modules/SecurityLevel.sys.mjs", OpenSearchEngine: "moz-src:///toolkit/components/search/OpenSearchEngine.sys.mjs", }); @@ -354,28 +353,6 @@ export class EngineURL { escapedSearchTerms, queryCharset ); - - if ( - lazy.SecurityLevelPrefs?.securityLevel === "safest" && - this.type === lazy.SearchUtils.URL_TYPE.SEARCH - ) { - let host = templateURI.host; - try { - host = Services.eTLD.getBaseDomainFromHost(host); - } catch (ex) { - lazy.logConsole.warn("Failed to get a FPD", ex, host); - } - if (host === "duckduckgo.com") { - templateURI.host = "html.duckduckgo.com"; - templateURI.pathname = "/html"; - } else if ( - host === - "duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion" - ) { - templateURI.pathname = "/html"; - } - } - if (this.method == "GET" && paramString) { // Query parameters may be specified in the template url AND in `this.params`. // Thus, we need to supply both with the search terms and join them. ===================================== toolkit/components/search/SearchEngineSelector.sys.mjs ===================================== @@ -315,6 +315,9 @@ export class SearchEngineSelector { * The name of the application. * @param {string} [options.version] * The version of the application. + * @param {boolean} [options.javascriptEnabled] + * Tell whether JS is enabled. If not, we will prefer plain HTML version of + * search engines, when available. * @returns {Promise<RefinedConfig>} * An object which contains the refined configuration with a filtered list * of search engines, and the identifiers for the application default engines. @@ -327,6 +330,7 @@ export class SearchEngineSelector { experiment, appName = Services.appinfo.name ?? "", version = Services.appinfo.version ?? "", + javascriptEnabled = true, }) { if (!this._configuration) { await this.getEngineConfiguration(); @@ -461,6 +465,17 @@ export class SearchEngineSelector { e => !e.optional ); + if (!javascriptEnabled) { + refinedSearchConfig.engines = refinedSearchConfig.engines.map(e => { + if (e.identifier === "ddg") { + e.urls.search.base = "https://html.duckduckgo.com/html"; + } else if (e.identifier === "ddg-onion") { + e.urls.search.base += "html"; + } + return e; + }); + } + if ( !refinedSearchConfig.appDefaultEngineId || !refinedSearchConfig.engines.find( ===================================== toolkit/components/search/SearchService.sys.mjs ===================================== @@ -24,6 +24,7 @@ ChromeUtils.defineESModuleGetters(lazy, { "moz-src:///toolkit/components/search/PolicySearchEngine.sys.mjs", Region: "resource://gre/modules/Region.sys.mjs", RemoteSettings: "resource://services-settings/remote-settings.sys.mjs", + SecurityLevelPrefs: "resource://gre/modules/SecurityLevel.sys.mjs", SearchEngine: "moz-src:///toolkit/components/search/SearchEngine.sys.mjs", SearchEngineSelector: "moz-src:///toolkit/components/search/SearchEngineSelector.sys.mjs", @@ -71,6 +72,7 @@ ChromeUtils.defineLazyGetter(lazy, "defaultOverrideAllowlist", () => { const TOPIC_LOCALES_CHANGE = "intl:app-locales-changed"; const QUIT_APPLICATION_TOPIC = "quit-application"; +const TOPIC_JSENABLED_CHANGED = "SecurityLevel:JavascriptEnabledChanged"; // The update timer for OpenSearch engines checks in once a day. const OPENSEARCH_UPDATE_TIMER_TOPIC = "search-engine-update-timer"; @@ -2634,6 +2636,7 @@ export class SearchService { channel: lazy.SearchUtils.MODIFIED_APP_CHANNEL, experiment: this._experimentPrefValue, distroID: lazy.SearchUtils.distroID ?? "", + javascriptEnabled: lazy.SecurityLevelPrefs.javascriptEnabled, }; for (let [key, value] of Object.entries(searchEngineSelectorProperties)) { @@ -3527,6 +3530,7 @@ export class SearchService { Services.obs.addObserver(this, lazy.SearchUtils.TOPIC_ENGINE_MODIFIED); Services.obs.addObserver(this, QUIT_APPLICATION_TOPIC); Services.obs.addObserver(this, TOPIC_LOCALES_CHANGE); + Services.obs.addObserver(this, TOPIC_JSENABLED_CHANGED); this._settings.addObservers(); @@ -3589,6 +3593,7 @@ export class SearchService { Services.obs.removeObserver(this, QUIT_APPLICATION_TOPIC); Services.obs.removeObserver(this, TOPIC_LOCALES_CHANGE); Services.obs.removeObserver(this, lazy.Region.REGION_TOPIC); + Services.obs.removeObserver(this, TOPIC_JSENABLED_CHANGED); } QueryInterface = ChromeUtils.generateQI([ @@ -3668,6 +3673,13 @@ export class SearchService { Ci.nsISearchService.CHANGE_REASON_REGION ).catch(console.error); break; + + case TOPIC_JSENABLED_CHANGED: + lazy.logConsole.debug("JavaScript toggled"); + this._maybeReloadEngines( + Ci.nsISearchService.CHANGE_REASON_CONFIG + ).catch(console.error); + break; } } ===================================== toolkit/components/securitylevel/SecurityLevel.sys.mjs ===================================== @@ -390,6 +390,8 @@ var initializeSecurityPrefs = function () { Services.prefs.setBoolPref(kCustomPref, false); Services.prefs.setIntPref(kSliderPref, effectiveIndex); } + // Determine the javascriptEnabled value *after* we have set kSliderPref. + SecurityLevelPrefs.updateJavascriptEnabled(); // Warn the user if they have booted the browser in a custom state, and have // not yet acknowledged it in a previous session. SecurityLevelPrefs.maybeWarnCustom(); @@ -566,6 +568,42 @@ export const SecurityLevelPrefs = { )?.[0]; }, + /** + * Cached value for whether javascript is enabled. `null` whilst undetermined. + * + * @type {?boolean} + */ + _javascriptEnabled: null, + + /** + * Whether javascript is enabled for web pages at the current security level. + * + * @type {boolean} + */ + get javascriptEnabled() { + if (this._javascriptEnabled === null) { + this.updateJavascriptEnabled(); + } + return this._javascriptEnabled; + }, + + /** + * Update the javascriptEnabled value. + */ + updateJavascriptEnabled() { + // NoScript will disable javascript for web pages at the safest security + // level. + const enabled = this.securityLevel !== "safest"; + if (enabled === this._javascriptEnabled) { + return; + } + this._javascriptEnabled = enabled; + Services.obs.notifyObservers( + null, + "SecurityLevel:JavascriptEnabledChanged" + ); + }, + /** * Set the desired security level just before a restart. * @@ -575,6 +613,10 @@ export const SecurityLevelPrefs = { */ setSecurityLevelBeforeRestart(level) { write_setting_to_prefs(this.SecurityLevels[level]); + // NOTE: Do not call `updateJavascriptEnabled`. We are about to restart, so + // consumers do not need to know about the change. + // Moreover, the change has not reached NoScript, which controls the + // javascript changes. }, /** @@ -729,6 +771,8 @@ export const SecurityLevelPrefs = { // still be marked as "custom" because: // 1. Some preferences require a browser restart to be applied. // 2. NoScript has not been updated with the new settings. + // NOTE: Do not call `updateJavascriptEnabled` because the change has not + // reached NoScript, which controls the javascript changes. this._tryShowNotifications({ restart: true, custom: true }); }, View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/8765cf34... -- View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/8765cf34... You're receiving this email because of your account on gitlab.torproject.org.