Verified Commit cefc9416 authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃
Browse files

fixup! Bug 8324: Prevent DNS proxy bypasses caused by Drag&Drop

Emergency modernization
parent 31443c6a
Loading
Loading
Loading
Loading
+6 −10
Original line number Diff line number Diff line
@@ -2,17 +2,13 @@
 * 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/. */

const { XPCOMUtils } = ChromeUtils.import(
  "resource://gre/modules/XPCOMUtils.jsm"
);

const lazy = {};

XPCOMUtils.defineLazyGetter(lazy, "gOpaqueDrag", () => {
  return Cc["@torproject.org/torbutton-dragDropFilter;1"].getService(
    Ci.nsISupports
  ).wrappedJSObject.opaqueDrag;
});
ChromeUtils.defineModuleGetter(
  lazy,
  "OpaqueDrag",
  "resource://torbutton/modules/DragDropFilter.jsm"
);

// This component is used for handling dragover and drop of urls.
//
@@ -59,7 +55,7 @@ ContentAreaDropListener.prototype = {
      data = dt.mozGetDataAt(type, i);
      if (data) {
        if (type === "application/x-torbrowser-opaque") {
          ({ type, value: data = "" } = lazy.gOpaqueDrag.get(data));
          ({ type, value: data = "" } = lazy.OpaqueDrag.retrieve(data));
        }
        let lines = data.split("\n");
        for (let i = 0, length = lines.length; i < length; i += 2) {
+7 −7
Original line number Diff line number Diff line
@@ -18,6 +18,12 @@ ChromeUtils.defineESModuleGetters(lazy, {
  Sqlite: "resource://gre/modules/Sqlite.sys.mjs",
});

ChromeUtils.defineModuleGetter(
  lazy,
  "OpaqueDrag",
  "resource://torbutton/modules/DragDropFilter.jsm"
);

XPCOMUtils.defineLazyGetter(lazy, "MOZ_ACTION_REGEX", () => {
  return /^moz-action:([^,]+),(.*)$/;
});
@@ -26,12 +32,6 @@ XPCOMUtils.defineLazyGetter(lazy, "gCryptoHash", () => {
  return Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash);
});

XPCOMUtils.defineLazyGetter(lazy, "gOpaqueDrag", () => {
  return Cc["@torproject.org/torbutton-dragDropFilter;1"].getService(
    Ci.nsISupports
  ).wrappedJSObject.opaqueDrag;
});

// On Mac OSX, the transferable system converts "\r\n" to "\n\n", where
// we really just want "\n". On other platforms, the transferable system
// converts "\r\n" to "\n".
@@ -1110,7 +1110,7 @@ export var PlacesUtils = {
    // We split on "\n"  because the transferable system converts "\r\n" to "\n"
    var nodes = [];
    if (type === "application/x-torbrowser-opaque") {
      ({ value: blob, type } = lazy.gOpaqueDrag.get(blob));
      ({ value: blob, type } = lazy.OpaqueDrag.retrieve(blob));
    }
    switch (type) {
      case this.TYPE_X_MOZ_PLACE:
+8 −0
Original line number Diff line number Diff line
@@ -15,4 +15,12 @@ Classes = [
        "jsm": "resource://torbutton/modules/TorbuttonLogger.jsm",
        "constructor": "TorbuttonLogger",
    },
    {
        "cid": "{f605ec27-d867-44b5-ad97-2a29276642c3}",
        "contract_ids": [
            "@torproject.org/torbutton-dragDropFilter;1"
        ],
        "jsm": "resource://torbutton/modules/DragDropFilter.jsm",
        "constructor": "DragDropFilter",
    },
]
+0 −4
Original line number Diff line number Diff line
@@ -6,10 +6,6 @@ torbutton.jar:

  content/torbutton.js                   (chrome/content/torbutton.js)

  components/    (components/*)
  modules/       (modules/*)

% resource torbutton %

% component {f605ec27-d867-44b5-ad97-2a29276642c3} %components/dragDropFilter.js
% contract @torproject.org/torbutton-dragDropFilter;1 {f605ec27-d867-44b5-ad97-2a29276642c3}
+37 −58
Original line number Diff line number Diff line
@@ -5,22 +5,32 @@
 * access to URLs (a potential proxy bypass vector).
 *************************************************************************/

var EXPORTED_SYMBOLS = ["DragDropFilter", "OpaqueDrag"];

const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");

const { XPCOMUtils } = ChromeUtils.import(
  "resource://gre/modules/XPCOMUtils.jsm"
);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");

XPCOMUtils.defineLazyModuleGetters(this, {
  ComponentUtils: "resource://gre/modules/ComponentUtils.jsm",
const lazy = {};

XPCOMUtils.defineLazyGetter(lazy, "logger", () => {
  // Keep the logger lazy, because it is used only in the parent process.
  // For some reason, Mozilla considers reading the preference linked to the
  // level in the children illegal (and triggers a crash when
  // fission.enforceBlocklistedPrefsInSubprocesses is true).
  // (Or maybe this crash used to happen when the logger was not lazy, and maybe
  // the preferences were not ready, yet?)
  const { ConsoleAPI } = ChromeUtils.importESModule(
    "resource://gre/modules/Console.sys.mjs"
  );
  return new ConsoleAPI({
    maxLogLevel: "warn",
    maxLogLevelPref: "browser.dragdropfilter.log_level",
    prefix: "DragDropFilter",
  });
});
XPCOMUtils.defineLazyGlobalGetters(this, ["crypto"]);

// Module specific constants
const kMODULE_NAME = "Torbutton Drag and Drop Handler";
const kCONTRACT_ID = "@torproject.org/torbutton-dragDropFilter;1";
const kMODULE_CID = Components.ID("f605ec27-d867-44b5-ad97-2a29276642c3");

const kInterfaces = [Ci.nsIObserver, Ci.nsIClassInfo];

const URLISH_TYPES = Object.freeze([
  "text/x-moz-url",
@@ -65,53 +75,28 @@ const OpaqueDrag = {
  },
};

function DragDropFilter() {
  this.logger = Cc["@torproject.org/torbutton-logger;1"].getService(
    Ci.nsISupports
  ).wrappedJSObject;
  this.logger.log(3, "Component Load 0: New DragDropFilter.");
  if (MAIN_PROCESS) {
class DragDropFilter {
  observe(subject, topic, data) {
    if (topic === "on-datatransfer-available") {
      lazy.logger.debug("The DataTransfer is available");
      this.filterDataTransferURLs(subject);
    } else if (topic === "profile-after-change" && MAIN_PROCESS) {
      lazy.logger.info(
        "Observed profile-after-change: registering the observer."
      );
      // We want to update our status in the main process only, in order to
      // serve the same opaque drag payload in every process.
      try {
        Services.obs.addObserver(this, "on-datatransfer-available");
      } catch (e) {
      this.logger.log(5, "Failed to register drag observer");
        lazy.logger.error("Failed to register drag observer", e);
      }
    }
  }

DragDropFilter.prototype = {
  QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),

  // make this an nsIClassInfo object
  flags: Ci.nsIClassInfo.DOM_OBJECT,
  classDescription: kMODULE_NAME,
  contractID: kCONTRACT_ID,
  classID: kMODULE_CID,

  // method of nsIClassInfo
  getInterfaces(count) {
    count.value = kInterfaces.length;
    return kInterfaces;
  },

  // method of nsIClassInfo
  getHelperForLanguage(count) {
    return null;
  },

  // method of nsIObserver
  observe(subject, topic, data) {
    if (topic === "on-datatransfer-available") {
      this.logger.log(3, "The DataTransfer is available");
      this.filterDataTransferURLs(subject);
    }
  },

  filterDataTransferURLs(aDataTransfer) {
    for (let i = 0, count = aDataTransfer.mozItemCount; i < count; ++i) {
      this.logger.log(3, `Inspecting the data transfer: ${i}.`);
      lazy.logger.debug(`Inspecting the data transfer: ${i}.`);
      const types = aDataTransfer.mozTypesAt(i);
      const urlType = "text/x-moz-url";
      // Fallback url type, to be parsed by this browser but not externally
@@ -133,10 +118,9 @@ DragDropFilter.prototype = {
        aDataTransfer.mozSetDataAt(INTERNAL_FALLBACK, opaqueKey, i);
      }
      for (const type of types) {
        this.logger.log(3, `Type is: ${type}.`);
        lazy.logger.debug(`Type is: ${type}.`);
        if (URLISH_TYPES.includes(type)) {
          this.logger.log(
            3,
          lazy.logger.info(
            `Removing transfer data ${aDataTransfer.mozGetDataAt(type, i)}`
          );
          for (const type of types) {
@@ -152,16 +136,11 @@ DragDropFilter.prototype = {
        }
      }
    }
  },
  }

  opaqueDrag: {
  opaqueDrag = {
    get(opaqueKey) {
      return OpaqueDrag.retrieve(opaqueKey);
    },
  },
  };

// Assign factory to global object.
const NSGetFactory = XPCOMUtils.generateNSGetFactory
  ? XPCOMUtils.generateNSGetFactory([DragDropFilter])
  : ComponentUtils.generateNSGetFactory([DragDropFilter]);
}
Loading