Commit f21d1c79 authored by Gijs Kruitbosch's avatar Gijs Kruitbosch
Browse files

Bug 1739929 - allow untrusted click/auxclick events to open one link per...

Bug 1739929 - allow untrusted click/auxclick events to open one link per transient user gesture, r=edgar

Differential Revision: https://phabricator.services.mozilla.com/D131868
parent d86a582b
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ ChromeUtils.defineModuleGetter(
class ClickHandlerChild extends JSWindowActorChild {
  handleEvent(event) {
    if (
      !event.isTrusted ||
      event.defaultPrevented ||
      event.button == 2 ||
      (event.type == "click" && event.button == 1)
@@ -58,6 +57,13 @@ class ClickHandlerChild extends JSWindowActorChild {
      return;
    }

    // For untrusted events, require a valid transient user gesture activation.
    // consumeTransientUserGestureActivation returns false if there isn't one,
    // and consumes it otherwise.
    if (!event.isTrusted && !ownerDoc.consumeTransientUserGestureActivation()) {
      return;
    }

    // Handle click events from about pages
    if (event.button == 0) {
      if (ownerDoc.documentURI.startsWith("about:blocked")) {
+4 −0
Original line number Diff line number Diff line
@@ -89,3 +89,7 @@ FINAL_TARGET_FILES.actors += [
    "WebRTCChild.jsm",
    "WebRTCParent.jsm",
]

BROWSER_CHROME_MANIFESTS += [
    "test/browser/browser.ini",
]
+3 −0
Original line number Diff line number Diff line
[browser_untrusted_click_event.js]
support-files =
  click.html
+31 −0
Original line number Diff line number Diff line
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

const TEST_PATH = getRootDirectory(gTestPath).replace(
  "chrome://mochitests/content",
  "https://example.com"
);

/**
 * Ensure that click handlers that prevent the default action but fire
 * a different click event that does open a tab are allowed to work.
 */
add_task(async function test_untrusted_click_opens_tab() {
  await BrowserTestUtils.withNewTab(TEST_PATH + "click.html", async browser => {
    let newTabOpened = BrowserTestUtils.waitForNewTab(
      gBrowser,
      "https://example.org/",
      true
    );
    info("clicking link with modifier pressed.");
    let eventObj = {};
    eventObj[AppConstants.platform == "macosx" ? "metaKey" : "ctrlKey"] = true;
    await BrowserTestUtils.synthesizeMouseAtCenter("#test", eventObj, browser);
    info("Waiting for new tab to open; if we timeout the test is broken.");
    let newTab = await newTabOpened;
    ok(newTab, "New tab should be opened.");
    BrowserTestUtils.removeTab(newTab);
  });
});
+38 −0
Original line number Diff line number Diff line
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Click a link whose event we intercept</title>
</head>
<body>

<a id="test" href="https://example.com/">click me</a>

<script>

  document.getElementById("test").addEventListener("click", originalClick => {
      const newLink = document.createElement("a");
      newLink.setAttribute("rel", "noreferrer");
      newLink.setAttribute("target", "_blank");
      newLink.setAttribute("href", "https://example.org/");


      document.body.appendChild(newLink);

      const evt = document.createEvent('MouseEvent');
      evt.initMouseEvent(
        "click", true, true, window, 0,
        originalClick.screenX, originalClick.screenY, originalClick.clientX, originalClick.clientY,
        originalClick.ctrlKey, originalClick.altKey, originalClick.shiftKey, originalClick.metaKey,
        originalClick.button, originalClick.relatedTarget
      );
      newLink.dispatchEvent(evt);


      originalClick.preventDefault();
      originalClick.stopPropagation();
  });

</script>
</body>
</html>
Loading