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:
Changes:
toolkit/components/search/SearchEngine.sys.mjs
| ... |
... |
@@ -14,7 +14,6 @@ const lazy = {}; |
|
14
|
14
|
ChromeUtils.defineESModuleGetters(lazy, {
|
|
15
|
15
|
SearchSettings: "moz-src:///toolkit/components/search/SearchSettings.sys.mjs",
|
|
16
|
16
|
SearchUtils: "moz-src:///toolkit/components/search/SearchUtils.sys.mjs",
|
|
17
|
|
- SecurityLevelPrefs: "resource://gre/modules/SecurityLevel.sys.mjs",
|
|
18
|
17
|
OpenSearchEngine:
|
|
19
|
18
|
"moz-src:///toolkit/components/search/OpenSearchEngine.sys.mjs",
|
|
20
|
19
|
});
|
| ... |
... |
@@ -354,28 +353,6 @@ export class EngineURL { |
|
354
|
353
|
escapedSearchTerms,
|
|
355
|
354
|
queryCharset
|
|
356
|
355
|
);
|
|
357
|
|
-
|
|
358
|
|
- if (
|
|
359
|
|
- lazy.SecurityLevelPrefs?.securityLevel === "safest" &&
|
|
360
|
|
- this.type === lazy.SearchUtils.URL_TYPE.SEARCH
|
|
361
|
|
- ) {
|
|
362
|
|
- let host = templateURI.host;
|
|
363
|
|
- try {
|
|
364
|
|
- host = Services.eTLD.getBaseDomainFromHost(host);
|
|
365
|
|
- } catch (ex) {
|
|
366
|
|
- lazy.logConsole.warn("Failed to get a FPD", ex, host);
|
|
367
|
|
- }
|
|
368
|
|
- if (host === "duckduckgo.com") {
|
|
369
|
|
- templateURI.host = "html.duckduckgo.com";
|
|
370
|
|
- templateURI.pathname = "/html";
|
|
371
|
|
- } else if (
|
|
372
|
|
- host ===
|
|
373
|
|
- "duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion"
|
|
374
|
|
- ) {
|
|
375
|
|
- templateURI.pathname = "/html";
|
|
376
|
|
- }
|
|
377
|
|
- }
|
|
378
|
|
-
|
|
379
|
356
|
if (this.method == "GET" && paramString) {
|
|
380
|
357
|
// Query parameters may be specified in the template url AND in `this.params`.
|
|
381
|
358
|
// 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 { |
|
315
|
315
|
* The name of the application.
|
|
316
|
316
|
* @param {string} [options.version]
|
|
317
|
317
|
* The version of the application.
|
|
|
318
|
+ * @param {boolean} [options._javascript_Enabled]
|
|
|
319
|
+ * Tell whether JS is enabled. If not, we will prefer plain HTML version of
|
|
|
320
|
+ * search engines, when available.
|
|
318
|
321
|
* @returns {Promise<RefinedConfig>}
|
|
319
|
322
|
* An object which contains the refined configuration with a filtered list
|
|
320
|
323
|
* of search engines, and the identifiers for the application default engines.
|
| ... |
... |
@@ -327,6 +330,7 @@ export class SearchEngineSelector { |
|
327
|
330
|
experiment,
|
|
328
|
331
|
appName = Services.appinfo.name ?? "",
|
|
329
|
332
|
version = Services.appinfo.version ?? "",
|
|
|
333
|
+ _javascript_Enabled = true,
|
|
330
|
334
|
}) {
|
|
331
|
335
|
if (!this._configuration) {
|
|
332
|
336
|
await this.getEngineConfiguration();
|
| ... |
... |
@@ -461,6 +465,17 @@ export class SearchEngineSelector { |
|
461
|
465
|
e => !e.optional
|
|
462
|
466
|
);
|
|
463
|
467
|
|
|
|
468
|
+ if (!_javascript_Enabled) {
|
|
|
469
|
+ refinedSearchConfig.engines = refinedSearchConfig.engines.map(e => {
|
|
|
470
|
+ if (e.identifier === "ddg") {
|
|
|
471
|
+ e.urls.search.base = "https://html.duckduckgo.com/html";
|
|
|
472
|
+ } else if (e.identifier === "ddg-onion") {
|
|
|
473
|
+ e.urls.search.base += "html";
|
|
|
474
|
+ }
|
|
|
475
|
+ return e;
|
|
|
476
|
+ });
|
|
|
477
|
+ }
|
|
|
478
|
+
|
|
464
|
479
|
if (
|
|
465
|
480
|
!refinedSearchConfig.appDefaultEngineId ||
|
|
466
|
481
|
!refinedSearchConfig.engines.find(
|
toolkit/components/search/SearchService.sys.mjs
| ... |
... |
@@ -24,6 +24,7 @@ ChromeUtils.defineESModuleGetters(lazy, { |
|
24
|
24
|
"moz-src:///toolkit/components/search/PolicySearchEngine.sys.mjs",
|
|
25
|
25
|
Region: "resource://gre/modules/Region.sys.mjs",
|
|
26
|
26
|
RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
|
|
|
27
|
+ SecurityLevelPrefs: "resource://gre/modules/SecurityLevel.sys.mjs",
|
|
27
|
28
|
SearchEngine: "moz-src:///toolkit/components/search/SearchEngine.sys.mjs",
|
|
28
|
29
|
SearchEngineSelector:
|
|
29
|
30
|
"moz-src:///toolkit/components/search/SearchEngineSelector.sys.mjs",
|
| ... |
... |
@@ -71,6 +72,7 @@ ChromeUtils.defineLazyGetter(lazy, "defaultOverrideAllowlist", () => { |
|
71
|
72
|
|
|
72
|
73
|
const TOPIC_LOCALES_CHANGE = "intl:app-locales-changed";
|
|
73
|
74
|
const QUIT_APPLICATION_TOPIC = "quit-application";
|
|
|
75
|
+const TOPIC_JSENABLED_CHANGED = "SecurityLevel:_javascript_EnabledChanged";
|
|
74
|
76
|
|
|
75
|
77
|
// The update timer for OpenSearch engines checks in once a day.
|
|
76
|
78
|
const OPENSEARCH_UPDATE_TIMER_TOPIC = "search-engine-update-timer";
|
| ... |
... |
@@ -2634,6 +2636,7 @@ export class SearchService { |
|
2634
|
2636
|
channel: lazy.SearchUtils.MODIFIED_APP_CHANNEL,
|
|
2635
|
2637
|
experiment: this._experimentPrefValue,
|
|
2636
|
2638
|
distroID: lazy.SearchUtils.distroID ?? "",
|
|
|
2639
|
+ _javascript_Enabled: lazy.SecurityLevelPrefs._javascript_Enabled,
|
|
2637
|
2640
|
};
|
|
2638
|
2641
|
|
|
2639
|
2642
|
for (let [key, value] of Object.entries(searchEngineSelectorProperties)) {
|
| ... |
... |
@@ -3527,6 +3530,7 @@ export class SearchService { |
|
3527
|
3530
|
Services.obs.addObserver(this, lazy.SearchUtils.TOPIC_ENGINE_MODIFIED);
|
|
3528
|
3531
|
Services.obs.addObserver(this, QUIT_APPLICATION_TOPIC);
|
|
3529
|
3532
|
Services.obs.addObserver(this, TOPIC_LOCALES_CHANGE);
|
|
|
3533
|
+ Services.obs.addObserver(this, TOPIC_JSENABLED_CHANGED);
|
|
3530
|
3534
|
|
|
3531
|
3535
|
this._settings.addObservers();
|
|
3532
|
3536
|
|
| ... |
... |
@@ -3589,6 +3593,7 @@ export class SearchService { |
|
3589
|
3593
|
Services.obs.removeObserver(this, QUIT_APPLICATION_TOPIC);
|
|
3590
|
3594
|
Services.obs.removeObserver(this, TOPIC_LOCALES_CHANGE);
|
|
3591
|
3595
|
Services.obs.removeObserver(this, lazy.Region.REGION_TOPIC);
|
|
|
3596
|
+ Services.obs.removeObserver(this, TOPIC_JSENABLED_CHANGED);
|
|
3592
|
3597
|
}
|
|
3593
|
3598
|
|
|
3594
|
3599
|
QueryInterface = ChromeUtils.generateQI([
|
| ... |
... |
@@ -3668,6 +3673,13 @@ export class SearchService { |
|
3668
|
3673
|
Ci.nsISearchService.CHANGE_REASON_REGION
|
|
3669
|
3674
|
).catch(console.error);
|
|
3670
|
3675
|
break;
|
|
|
3676
|
+
|
|
|
3677
|
+ case TOPIC_JSENABLED_CHANGED:
|
|
|
3678
|
+ lazy.logConsole.debug("_javascript_ toggled");
|
|
|
3679
|
+ this._maybeReloadEngines(
|
|
|
3680
|
+ Ci.nsISearchService.CHANGE_REASON_CONFIG
|
|
|
3681
|
+ ).catch(console.error);
|
|
|
3682
|
+ break;
|
|
3671
|
3683
|
}
|
|
3672
|
3684
|
}
|
|
3673
|
3685
|
|
toolkit/components/securitylevel/SecurityLevel.sys.mjs
| ... |
... |
@@ -390,6 +390,8 @@ var initializeSecurityPrefs = function () { |
|
390
|
390
|
Services.prefs.setBoolPref(kCustomPref, false);
|
|
391
|
391
|
Services.prefs.setIntPref(kSliderPref, effectiveIndex);
|
|
392
|
392
|
}
|
|
|
393
|
+ // Determine the _javascript_Enabled value *after* we have set kSliderPref.
|
|
|
394
|
+ SecurityLevelPrefs.updateJavascriptEnabled();
|
|
393
|
395
|
// Warn the user if they have booted the browser in a custom state, and have
|
|
394
|
396
|
// not yet acknowledged it in a previous session.
|
|
395
|
397
|
SecurityLevelPrefs.maybeWarnCustom();
|
| ... |
... |
@@ -566,6 +568,42 @@ export const SecurityLevelPrefs = { |
|
566
|
568
|
)?.[0];
|
|
567
|
569
|
},
|
|
568
|
570
|
|
|
|
571
|
+ /**
|
|
|
572
|
+ * Cached value for whether _javascript_ is enabled. `null` whilst undetermined.
|
|
|
573
|
+ *
|
|
|
574
|
+ * @type {?boolean}
|
|
|
575
|
+ */
|
|
|
576
|
+ _javascriptEnabled: null,
|
|
|
577
|
+
|
|
|
578
|
+ /**
|
|
|
579
|
+ * Whether _javascript_ is enabled for web pages at the current security level.
|
|
|
580
|
+ *
|
|
|
581
|
+ * @type {boolean}
|
|
|
582
|
+ */
|
|
|
583
|
+ get _javascript_Enabled() {
|
|
|
584
|
+ if (this._javascriptEnabled === null) {
|
|
|
585
|
+ this.updateJavascriptEnabled();
|
|
|
586
|
+ }
|
|
|
587
|
+ return this._javascriptEnabled;
|
|
|
588
|
+ },
|
|
|
589
|
+
|
|
|
590
|
+ /**
|
|
|
591
|
+ * Update the _javascript_Enabled value.
|
|
|
592
|
+ */
|
|
|
593
|
+ updateJavascriptEnabled() {
|
|
|
594
|
+ // NoScript will disable _javascript_ for web pages at the safest security
|
|
|
595
|
+ // level.
|
|
|
596
|
+ const enabled = this.securityLevel !== "safest";
|
|
|
597
|
+ if (enabled === this._javascriptEnabled) {
|
|
|
598
|
+ return;
|
|
|
599
|
+ }
|
|
|
600
|
+ this._javascriptEnabled = enabled;
|
|
|
601
|
+ Services.obs.notifyObservers(
|
|
|
602
|
+ null,
|
|
|
603
|
+ "SecurityLevel:_javascript_EnabledChanged"
|
|
|
604
|
+ );
|
|
|
605
|
+ },
|
|
|
606
|
+
|
|
569
|
607
|
/**
|
|
570
|
608
|
* Set the desired security level just before a restart.
|
|
571
|
609
|
*
|
| ... |
... |
@@ -575,6 +613,10 @@ export const SecurityLevelPrefs = { |
|
575
|
613
|
*/
|
|
576
|
614
|
setSecurityLevelBeforeRestart(level) {
|
|
577
|
615
|
write_setting_to_prefs(this.SecurityLevels[level]);
|
|
|
616
|
+ // NOTE: Do not call `updateJavascriptEnabled`. We are about to restart, so
|
|
|
617
|
+ // consumers do not need to know about the change.
|
|
|
618
|
+ // Moreover, the change has not reached NoScript, which controls the
|
|
|
619
|
+ // _javascript_ changes.
|
|
578
|
620
|
},
|
|
579
|
621
|
|
|
580
|
622
|
/**
|
| ... |
... |
@@ -729,6 +771,8 @@ export const SecurityLevelPrefs = { |
|
729
|
771
|
// still be marked as "custom" because:
|
|
730
|
772
|
// 1. Some preferences require a browser restart to be applied.
|
|
731
|
773
|
// 2. NoScript has not been updated with the new settings.
|
|
|
774
|
+ // NOTE: Do not call `updateJavascriptEnabled` because the change has not
|
|
|
775
|
+ // reached NoScript, which controls the _javascript_ changes.
|
|
732
|
776
|
|
|
733
|
777
|
this._tryShowNotifications({ restart: true, custom: true });
|
|
734
|
778
|
},
|
|