[tor-commits] [Git][tpo/applications/tor-browser][tor-browser-115.6.0esr-13.0-1] fixup! Bug 40458: Implement .tor.onion aliases
ma1 (@ma1)
git at gitlab.torproject.org
Mon Jan 8 19:09:38 UTC 2024
ma1 pushed to branch tor-browser-115.6.0esr-13.0-1 at The Tor Project / Applications / Tor Browser
Commits:
e4373331 by hackademix at 2024-01-08T20:09:08+01:00
fixup! Bug 40458: Implement .tor.onion aliases
Bug 42099: Blind cross-site .onion requests.
- - - - -
3 changed files:
- browser/components/onionservices/OnionAliasStore.jsm
- + browser/components/onionservices/TorRequestWatch.sys.mjs
- browser/components/onionservices/moz.build
Changes:
=====================================
browser/components/onionservices/OnionAliasStore.jsm
=====================================
@@ -12,11 +12,10 @@ const { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm");
const lazy = {};
-ChromeUtils.defineModuleGetter(
- lazy,
- "JSONFile",
- "resource://gre/modules/JSONFile.jsm"
-);
+ChromeUtils.defineESModuleGetters(lazy, {
+ JSONFile: "resource://gre/modules/JSONFile.sys.mjs",
+ TorRequestWatch: "resource:///modules/TorRequestWatch.sys.mjs",
+});
/* OnionAliasStore observer topics */
const OnionAliasStoreTopics = Object.freeze({
@@ -281,6 +280,7 @@ class _OnionAliasStore {
}
async init() {
+ lazy.TorRequestWatch.start();
await this._loadSettings();
if (this.enabled) {
await this._startUpdates();
@@ -295,6 +295,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.jsm",
"OnionLocationChild.jsm",
"OnionLocationParent.jsm",
+ "TorRequestWatch.sys.mjs",
]
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/e4373331d54733119fea662fb9b83137921d3ec7
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/commit/e4373331d54733119fea662fb9b83137921d3ec7
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/20240108/e6be8d4e/attachment-0001.htm>
More information about the tor-commits
mailing list