[tbb-commits] [torbutton/master] Bug 26128: Adapt security slider to WebExtensions version of NoScript

gk at torproject.org gk at torproject.org
Tue Jun 19 08:35:39 UTC 2018


commit 3e1c144a729f373b3ee70fd8d2a16646b2b6ad12
Author: Arthur Edelstein <arthuredelstein at gmail.com>
Date:   Wed Jun 6 21:54:58 2018 -0700

    Bug 26128: Adapt security slider to WebExtensions version of NoScript
    
    We try to maintain the same security slider behavior as for the
    legacy version of NoScript.
    
    This patch uses a few tricks:
    
    1. Using a LegacyExtensionContext (defined in LegacyExtensionsUtils.jsm)
       to send JSON objects to NoScript via sendMessage.
    2. Taking advantage of an existing invocation of
       browser.runtime.onMessage.addListener(...) in NoScript's code that accepts
       a JSON object for updating NoScript's settings.
    3. Providing NoScript with settings for a "site" whose "domain" is "http:",
       which causes NoScript to match non-https sites.
    
    (Thanks to Sukhbir Singh for help.)
---
 src/chrome/content/torbutton.js |   2 +
 src/modules/noscript-control.js | 126 ++++++++++++++++++++++++++++++++++++++++
 src/modules/security-prefs.js   |   8 +--
 3 files changed, 131 insertions(+), 5 deletions(-)

diff --git a/src/chrome/content/torbutton.js b/src/chrome/content/torbutton.js
index 7f750bc..11548d4 100644
--- a/src/chrome/content/torbutton.js
+++ b/src/chrome/content/torbutton.js
@@ -11,6 +11,7 @@ let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
 let { showDialog } = Cu.import("resource://torbutton/modules/utils.js", {});
 let { getLocale, unescapeTorString } = Cu.import("resource://torbutton/modules/utils.js", {});
 let SecurityPrefs = Cu.import("resource://torbutton/modules/security-prefs.js", {});
+let NoScriptControl = Cu.import("resource://torbutton/modules/noscript-control.js", {});
 let { bindPrefAndInit, observe } = Cu.import("resource://torbutton/modules/utils.js", {});
 
 Cu.importGlobalProperties(["XMLHttpRequest"]);
@@ -242,6 +243,7 @@ function torbutton_init() {
     torbutton_log(3, 'called init()');
 
     SecurityPrefs.initialize();
+    NoScriptControl.initialize();
 
     if (m_tb_wasinited) {
         return;
diff --git a/src/modules/noscript-control.js b/src/modules/noscript-control.js
new file mode 100644
index 0000000..6270efe
--- /dev/null
+++ b/src/modules/noscript-control.js
@@ -0,0 +1,126 @@
+// # NoScript settings control (for binding to Security Slider)
+
+/* jshint esversion:6 */
+
+// ## Utilities
+
+const { utils: Cu } = Components;
+const { LegacyExtensionContext } =
+      Cu.import("resource://gre/modules/LegacyExtensionsUtils.jsm", {});
+const { bindPrefAndInit } =
+      Cu.import("resource://torbutton/modules/utils.js", {});
+
+// ## NoScript settings
+
+// Minimum and maximum capability states as controlled by NoScript.
+const max_caps = ["fetch", "font", "frame", "media", "other", "script", "webgl"];
+const min_caps = ["frame", "other"];
+
+// Untrusted capabilities for [Standard, Safer, Safest] safety levels.
+const untrusted_caps = [
+  max_caps, // standard safety: neither http nor https
+  ["frame", "font", "other"], // safer: http
+  min_caps, // safest: neither http nor https
+];
+
+// Default capabilities for [Standard, Safer, Safest] safety levels.
+const default_caps = [
+  max_caps, // standard: both http and https
+  ["fetch", "font", "frame", "other", "script", "webgl"], // safer: https only
+  min_caps, // safest: both http and https
+];
+
+// __noscriptSettings(safetyLevel)__.
+// Produces NoScript settings with policy according to
+// the safetyLevel which can be:
+// 0 = Standard, 1 = Safer, 2 = Safest
+//
+// At the "Standard" safety level, we leave all sites at
+// default with maximal capabilities. Essentially no content
+// is blocked.
+//
+// At "Safer", we set all http sites to untrusted,
+// and all https sites to default. Scripts are only permitted
+// on https sites. Neither type of site is supposed to allow
+// media, but both allow fonts (as we used in legacy NoScript).
+//
+// At "Safest", all sites are at default with minimal
+// capabilities. Most things are blocked.
+let noscriptSettings = safetyLevel => (
+  {
+    "type": "NoScript.updateSettings",
+    "policy": {
+      "DEFAULT": {
+        "capabilities": default_caps[safetyLevel],
+        "temp": false
+      },
+      "TRUSTED": {
+        "capabilities": max_caps,
+        "temp": false
+      },
+      "UNTRUSTED": {
+        "capabilities": untrusted_caps[safetyLevel],
+        "temp": false
+      },
+      "sites": {
+        "trusted": [],
+        "untrusted": [[], ["http:"], []][safetyLevel],
+        "custom": {},
+        "temp": []
+      },
+      "enforced": true,
+      "autoAllowTop": false
+    },
+   "tabId": -1
+  });
+
+// ## Communications
+
+// The extension ID for NoScript (WebExtension)
+const noscriptID = "{73a6fe31-595d-460b-a920-fcc0f8843232}";
+
+// A mock extension object that can communicate with another extension
+// via the WebExtensions sendMessage/onMessage mechanism.
+let extensionContext = new LegacyExtensionContext({ id : noscriptID });
+
+// The component that handles WebExtensions' sendMessage.
+let messageManager = extensionContext.messenger.messageManagers[0];
+
+// __setNoScriptSettings(settings)__.
+// NoScript listens for internal settings with onMessage. We can send
+// a new settings JSON object according to NoScript's
+// protocol and these are accepted! See the use of
+// `browser.runtime.onMessage.addListener(...)` in NoScript's bg/main.js.
+let sendNoScriptSettings = settings =>
+    extensionContext.messenger.sendMessage(messageManager, settings, noscriptID);
+
+// __setNoScriptSafetyLevel(safetyLevel)__.
+// Set NoScript settings according to a particular safety level
+// (security slider level): 0 = Standard, 1 = Safer, 2 = Safest
+let setNoScriptSafetyLevel = safetyLevel =>
+    sendNoScriptSettings(noscriptSettings(safetyLevel));
+
+// ## Slider binding
+
+// __securitySliderToSafetyLevel(sliderState)__.
+// Converts the "extensions.torbutton.security_slider" pref value
+// to a "safety level" value: 0 = Standard, 1 = Safer, 2 = Safest
+let securitySliderToSafetyLevel = sliderState => [undefined, 2, 1, 1, 0][sliderState];
+
+// Ensure binding only occurs once.
+let initialized = false;
+
+// __initialize()__.
+// The main function that binds the NoScript settings to the security
+// slider pref state.
+var initialize = () => {
+  if (initialized) {
+    return;
+  }
+  bindPrefAndInit(
+    "extensions.torbutton.security_slider",
+    sliderState => setNoScriptSafetyLevel(securitySliderToSafetyLevel(sliderState)));
+};
+
+// Export initialize() function for external use.
+let EXPORTED_SYMBOLS = ["initialize"];
diff --git a/src/modules/security-prefs.js b/src/modules/security-prefs.js
index 3d3630b..d269a1f 100644
--- a/src/modules/security-prefs.js
+++ b/src/modules/security-prefs.js
@@ -16,19 +16,17 @@ let log = (level, msg) => logger.log(level, msg);
 // __kSecuritySettings__.
 // A table of all prefs bound to the security slider, and the value
 // for each security setting. Note that 2-m and 3-m are identical,
-// corresponding to the old 2-medium-high setting.
+// corresponding to the old 2-medium-high setting. We also separately
+// bind NoScript settings to the extensions.torbutton.security_slider
+// (see noscript-control.js).
 const kSecuritySettings = {
   // Preference name :                        [0, 1-high 2-m    3-m    4-low]
   "javascript.options.ion" :                  [,  false, false, false, true ],
   "javascript.options.baselinejit" :          [,  false, false, false, true ],
   "javascript.options.native_regexp" :        [,  false, false, false, true ],
-  "noscript.forbidMedia" :                    [,  true,  true,  true,  false],
   "media.webaudio.enabled" :                  [,  false, false, false, true ],
   "mathml.disabled" :                         [,  true,  true,  true,  false],
   "gfx.font_rendering.opentype_svg.enabled" : [,  false, false, false, true ],
-  "noscript.global" :                         [,  false, false, false, true ],
-  "noscript.globalHttpsWhitelist" :           [,  false, true,  true,  false],
-  "noscript.forbidFonts" :                    [,  true,  false, false, false],
   "svg.in-content.enabled" :                  [,  false, true,  true,  true ],
 };
 





More information about the tbb-commits mailing list