fune/browser/extensions/doh-rollout/heuristics.js
Nihanth Subramanya a25e8fd518 Bug 1598223 - Clean up background scripts. r=mixedpuppy,maxxcrawford
Differential Revision: https://phabricator.services.mozilla.com/D54624

--HG--
extra : moz-landing-system : lando
2019-11-28 19:14:10 +00:00

146 lines
4 KiB
JavaScript

/* 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/. */
"use strict";
/* global browser */
/* exported runHeuristics */
const GLOBAL_CANARY = "use-application-dns.net";
const NXDOMAIN_ERR = "NS_ERROR_UNKNOWN_HOST";
async function dnsLookup(hostname) {
let flags = ["disable_trr", "disable_ipv6", "bypass_cache"];
let addresses, err;
try {
let response = await browser.dns.resolve(hostname, flags);
addresses = response.addresses;
} catch (e) {
addresses = [null];
err = e.message;
}
return { addresses, err };
}
async function dnsListLookup(domainList) {
let results = [];
for (let domain of domainList) {
let { addresses } = await dnsLookup(domain);
results = results.concat(addresses);
}
return results;
}
async function safeSearch() {
const providerList = [
{
name: "google",
unfiltered: ["www.google.com", "google.com"],
safeSearch: ["forcesafesearch.google.com"],
},
{
name: "youtube",
unfiltered: [
"www.youtube.com",
"m.youtube.com",
"youtubei.googleapis.com",
"youtube.googleapis.com",
"www.youtube-nocookie.com",
],
safeSearch: ["restrict.youtube.com", "restrictmoderate.youtube.com"],
},
];
// Compare strict domain lookups to non-strict domain lookups
let safeSearchChecks = {};
for (let provider of providerList) {
let providerName = provider.name;
safeSearchChecks[providerName] = "enable_doh";
let results = {};
results.unfilteredAnswers = await dnsListLookup(provider.unfiltered);
results.safeSearchAnswers = await dnsListLookup(provider.safeSearch);
// Given a provider, check if the answer for any safe search domain
// matches the answer for any default domain
for (let answer of results.safeSearchAnswers) {
if (answer && results.unfilteredAnswers.includes(answer)) {
safeSearchChecks[providerName] = "disable_doh";
}
}
}
return safeSearchChecks;
}
async function zscalerCanary() {
const ZSCALER_CANARY = "sitereview.zscaler.com";
let { addresses } = await dnsLookup(ZSCALER_CANARY);
for (let address of addresses) {
if (
["213.152.228.242", "199.168.151.251", "8.25.203.30"].includes(address)
) {
// if sitereview.zscaler.com resolves to either one of the 3 IPs above,
// Zscaler Shift service is in use, don't enable DoH
return "disable_doh";
}
}
return "enable_doh";
}
// TODO: Confirm the expected behavior when filtering is on
async function globalCanary() {
let { addresses, err } = await dnsLookup(GLOBAL_CANARY);
if (err === NXDOMAIN_ERR || !addresses.length) {
return "disable_doh";
}
return "enable_doh";
}
async function modifiedRoots() {
// Check for presence of enterprise_roots cert pref. If enabled, disable DoH
let rootsEnabled = await browser.experiments.preferences.getBoolPref(
"security.enterprise_roots.enabled",
false
);
if (rootsEnabled) {
return "disable_doh";
}
return "enable_doh";
}
async function runHeuristics() {
let safeSearchChecks = await safeSearch();
let zscalerCheck = await zscalerCanary();
let canaryCheck = await globalCanary();
let modifiedRootsCheck = await modifiedRoots();
// Check other heuristics through privileged code
let browserParentCheck = await browser.experiments.heuristics.checkParentalControls();
let enterpriseCheck = await browser.experiments.heuristics.checkEnterprisePolicies();
let thirdPartyRootsCheck = await browser.experiments.heuristics.checkThirdPartyRoots();
// Return result of each heuristic
return {
google: safeSearchChecks.google,
youtube: safeSearchChecks.youtube,
zscalerCanary: zscalerCheck,
canary: canaryCheck,
modifiedRoots: modifiedRootsCheck,
browserParent: browserParentCheck,
thirdPartyRoots: thirdPartyRootsCheck,
policy: enterpriseCheck,
};
}