[tor-commits] [Git][tpo/applications/tor-browser][tor-browser-115.6.0esr-13.5-1] fixup! Bug 40458: Implement .tor.onion aliases

ma1 (@ma1) git at gitlab.torproject.org
Wed Dec 20 16:12:55 UTC 2023



ma1 pushed to branch tor-browser-115.6.0esr-13.5-1 at The Tor Project / Applications / Tor Browser


Commits:
d823a7e7 by hackademix at 2023-12-20T17:06:45+01:00
fixup! Bug 40458: Implement .tor.onion aliases

Bug 42099: Blind cross-site .onion requests.

- - - - -


3 changed files:

- browser/components/onionservices/OnionAliasStore.sys.mjs
- + browser/components/onionservices/TorRequestWatch.sys.mjs
- browser/components/onionservices/moz.build


Changes:

=====================================
browser/components/onionservices/OnionAliasStore.sys.mjs
=====================================
@@ -7,6 +7,7 @@ const lazy = {};
 
 ChromeUtils.defineESModuleGetters(lazy, {
   JSONFile: "resource://gre/modules/JSONFile.sys.mjs",
+  TorRequestWatch: "resource:///modules/TorRequestWatch.sys.mjs",
 });
 
 /* OnionAliasStore observer topics */
@@ -272,6 +273,7 @@ class _OnionAliasStore {
   }
 
   async init() {
+    lazy.TorRequestWatch.start();
     await this._loadSettings();
     if (this.enabled) {
       await this._startUpdates();
@@ -286,6 +288,7 @@ class _OnionAliasStore {
     }
     this._rulesetTimeout = null;
     Services.prefs.removeObserver(kPrefOnionAliasEnabled, this);
+    lazy.TorRequestWatch.stop();
   }
 
   async getChannels() {


=====================================
browser/components/onionservices/TorRequestWatch.sys.mjs
=====================================
@@ -0,0 +1,124 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * This module implements Tor-specific Web Request policies, such as
+ * preventing observable cross-site requests to .tor.onion and .bit.onion sites.
+ */
+
+import { ConsoleAPI } from "resource://gre/modules/Console.sys.mjs";
+
+const log = new ConsoleAPI({
+  maxLogLevel: "warn",
+  maxLogLevelPref: "browser.torRequestWatch.log_level",
+  prefix: "TorRequestWatch",
+});
+
+class RequestObserver {
+  static #topics = [
+    "http-on-modify-request",
+    "http-on-examine-response",
+    "http-on-examine-cached-response",
+    "http-on-examine-merged-response",
+  ];
+  #asObserver(addOrRemove) {
+    const action = Services.obs[`${addOrRemove}Observer`].bind(Services.obs);
+    for (const topic of RequestObserver.#topics) {
+      action(this, topic);
+    }
+  }
+
+  start() {
+    this.#asObserver("add");
+    log.debug("Started");
+  }
+  stop() {
+    this.#asObserver("remove");
+    log.debug("Stopped");
+  }
+
+  // nsIObserver implementation
+  observe(subject, topic, data) {
+    try {
+      let channel = ChannelWrapper.get(
+        subject.QueryInterface(Ci.nsIHttpChannel)
+      );
+      switch (topic) {
+        case "http-on-modify-request":
+          this.onRequest(channel);
+          break;
+        case "http-on-examine-cached-response":
+        case "http-on-examine-merged-response":
+          channel.isCached = true;
+        // falls through
+        case "http-on-examine-response":
+          this.onResponse(channel);
+          break;
+      }
+    } catch (e) {
+      log.error(e);
+    }
+  }
+
+  onRequest(channel) {
+    if (this.shouldBlind(channel, channel.documentURL)) {
+      log.warn(`Blocking cross-site ${channel.finalURL} ${channel.type} load.`);
+      channel.cancel(Cr.NS_ERROR_ABORT);
+    }
+  }
+  onResponse(channel) {
+    if (!channel.documentURL && this.shouldBlind(channel, channel.originURL)) {
+      const COOP = "cross-origin-opener-policy";
+      // we break window.opener references if needed to mitigate XS-Leaks
+      for (let h of channel.getResponseHeaders()) {
+        if (h.name.toLowerCase() === COOP && h.value === "same-origin") {
+          log.debug(`${COOP} is already same-origin, nothing to do.`);
+          return;
+        }
+      }
+      log.warn(`Blinding cross-site ${channel.finalURL} load.`);
+      channel.setResponseHeader(COOP, "same-origin-allow-popups");
+    }
+  }
+
+  isCrossOrigin(url1, url2) {
+    return new URL(url1).origin !== new URL(url2).origin;
+  }
+  shouldBlindCrossOrigin(uri) {
+    try {
+      let { host } = uri;
+      if (host.endsWith(".onion")) {
+        const previousPart = host.slice(-10, -6);
+        return (
+          previousPart && (previousPart === ".tor" || previousPart === ".bit")
+        );
+      }
+    } catch (e) {
+      // no host
+    }
+    return false;
+  }
+  shouldBlind(channel, sourceURL) {
+    return (
+      sourceURL &&
+      this.shouldBlindCrossOrigin(channel.finalURI) &&
+      this.isCrossOrigin(channel.finalURL, sourceURL)
+    );
+  }
+}
+
+let observer;
+export const TorRequestWatch = {
+  start() {
+    if (!observer) {
+      (observer = new RequestObserver()).start();
+    }
+  },
+  stop() {
+    if (observer) {
+      observer.stop();
+      observer = null;
+    }
+  },
+};


=====================================
browser/components/onionservices/moz.build
=====================================
@@ -4,4 +4,5 @@ EXTRA_JS_MODULES += [
     "OnionAliasStore.sys.mjs",
     "OnionLocationChild.sys.mjs",
     "OnionLocationParent.sys.mjs",
+    "TorRequestWatch.sys.mjs",
 ]



View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/d823a7e72ba20e816ca09aed6e8efd59b5166ca8

-- 
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/d823a7e72ba20e816ca09aed6e8efd59b5166ca8
You're receiving this email because of your account on gitlab.torproject.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tor-commits/attachments/20231220/8f8d8518/attachment-0001.htm>


More information about the tor-commits mailing list