tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_ext_native_messaging_permissions.js (5676B)


      1 "use strict";
      2 
      3 const server = createHttpServer({ hosts: ["example.com"] });
      4 server.registerPathHandler("/dum", (request, response) => {
      5  response.setStatusLine(request.httpVersion, 200, "OK");
      6  response.setHeader("Content-Type", "text/html; charset=utf-8", false);
      7  response.write("<!DOCTYPE html><html></html>");
      8 });
      9 
     10 async function testNativeMessaging({
     11  isPrivileged = false,
     12  permissions,
     13  testBackground,
     14  testContent,
     15 }) {
     16  async function runTest(testFn, completionMessage) {
     17    try {
     18      dump(`Running test before sending ${completionMessage}\n`);
     19      await testFn();
     20    } catch (e) {
     21      browser.test.fail(`Unexpected error: ${e}`);
     22    }
     23    browser.test.sendMessage(completionMessage);
     24  }
     25  const extension = ExtensionTestUtils.loadExtension({
     26    isPrivileged,
     27    background: `(${runTest})(${testBackground}, "background_done");`,
     28    manifest: {
     29      content_scripts: [
     30        {
     31          run_at: "document_end",
     32          js: ["test.js"],
     33          matches: ["http://example.com/dummy"],
     34        },
     35      ],
     36      permissions,
     37    },
     38    files: {
     39      "test.js": `(${runTest})(${testContent}, "content_done");`,
     40    },
     41  });
     42 
     43  // Run background script.
     44  await extension.startup();
     45  await extension.awaitMessage("background_done");
     46 
     47  // Run content script.
     48  const page = await ExtensionTestUtils.loadContentPage(
     49    "http://example.com/dummy"
     50  );
     51  await extension.awaitMessage("content_done");
     52  await page.close();
     53 
     54  await extension.unload();
     55 }
     56 
     57 // Checks that unprivileged extensions cannot use any of the nativeMessaging
     58 // APIs on Android.
     59 add_task(async function test_nativeMessaging_unprivileged() {
     60  function testScript() {
     61    browser.test.assertEq(
     62      browser.runtime.connectNative,
     63      undefined,
     64      "connectNative should not be available in unprivileged extensions"
     65    );
     66    browser.test.assertEq(
     67      browser.runtime.sendNativeMessage,
     68      undefined,
     69      "sendNativeMessage should not be available in unprivileged extensions"
     70    );
     71  }
     72 
     73  const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => {
     74    await testNativeMessaging({
     75      isPrivileged: false,
     76      permissions: [
     77        "geckoViewAddons",
     78        "nativeMessaging",
     79        "nativeMessagingFromContent",
     80      ],
     81      testBackground: testScript,
     82      testContent: testScript,
     83    });
     84  });
     85  AddonTestUtils.checkMessages(messages, {
     86    expected: [
     87      { message: /Invalid extension permission: geckoViewAddons/ },
     88      { message: /Invalid extension permission: nativeMessaging/ },
     89      { message: /Invalid extension permission: nativeMessagingFromContent/ },
     90    ],
     91  });
     92 });
     93 
     94 // Checks that privileged extensions can still not use native messaging without
     95 // the geckoViewAddons permission.
     96 add_task(async function test_geckoViewAddons_missing() {
     97  const ERROR_NATIVE_MESSAGE_FROM_BACKGROUND =
     98    "Native manifests are not supported on android";
     99  const ERROR_NATIVE_MESSAGE_FROM_CONTENT =
    100    /^Native messaging not allowed: \{.*"envType":"content_child","url":"http:\/\/example\.com\/dummy"\,"origin":"http:\/\/example\.com"}$/;
    101 
    102  async function testBackground() {
    103    await browser.test.assertRejects(
    104      browser.runtime.sendNativeMessage("dummy_nativeApp", "DummyMsg"),
    105      // Redacted error: ERROR_NATIVE_MESSAGE_FROM_BACKGROUND
    106      "An unexpected error occurred",
    107      "Background script cannot use nativeMessaging without geckoViewAddons"
    108    );
    109  }
    110  async function testContent() {
    111    await browser.test.assertRejects(
    112      browser.runtime.sendNativeMessage("dummy_nativeApp", "DummyMsg"),
    113      // Redacted error: ERROR_NATIVE_MESSAGE_FROM_CONTENT
    114      "An unexpected error occurred",
    115      "Content script cannot use nativeMessaging without geckoViewAddons"
    116    );
    117  }
    118 
    119  const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => {
    120    await testNativeMessaging({
    121      isPrivileged: true,
    122      permissions: ["nativeMessaging", "nativeMessagingFromContent"],
    123      testBackground,
    124      testContent,
    125    });
    126  });
    127  AddonTestUtils.checkMessages(messages, {
    128    expected: [
    129      { errorMessage: ERROR_NATIVE_MESSAGE_FROM_BACKGROUND },
    130      { errorMessage: ERROR_NATIVE_MESSAGE_FROM_CONTENT },
    131    ],
    132  });
    133 });
    134 
    135 // Checks that privileged extensions cannot use native messaging from content
    136 // without the nativeMessagingFromContent permission.
    137 add_task(async function test_nativeMessagingFromContent_missing() {
    138  const ERROR_NATIVE_MESSAGE_FROM_CONTENT_NO_PERM =
    139    /^Unexpected messaging sender: \{.*"envType":"content_child","url":"http:\/\/example\.com\/dummy"\,"origin":"http:\/\/example\.com"}$/;
    140  function testBackground() {
    141    // sendNativeMessage / connectNative are expected to succeed, but we
    142    // are not testing that here because XpcshellTestRunnerService does not
    143    // have a WebExtension.MessageDelegate that handles the message.
    144    // There are plenty of mochitests that rely on connectNative, so we are
    145    // not testing that here.
    146  }
    147  async function testContent() {
    148    await browser.test.assertRejects(
    149      browser.runtime.sendNativeMessage("dummy_nativeApp", "DummyMsg"),
    150      // Redacted error: ERROR_NATIVE_MESSAGE_FROM_CONTENT_NO_PERM
    151      "An unexpected error occurred",
    152      "Trying to get through to native messaging but without luck"
    153    );
    154  }
    155 
    156  const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => {
    157    await testNativeMessaging({
    158      isPrivileged: true,
    159      permissions: ["geckoViewAddons", "nativeMessaging"],
    160      testBackground,
    161      testContent,
    162    });
    163  });
    164  AddonTestUtils.checkMessages(messages, {
    165    expected: [{ errorMessage: ERROR_NATIVE_MESSAGE_FROM_CONTENT_NO_PERM }],
    166  });
    167 });