// Based on https://github.com/mdn/webextensions-examples/blob/main/root-cert-stats/background.js let certs = []; // On header receive, inspect cert and update app icon as required async function onHeaderReceive(details) { if (details.tabId < 0) // tabId < 0 means non-user tab return; try { await certInspectUpdate(details.requestId, details.tabId); } catch(error) { console.error(error); } } async function certInspectUpdate(requestId, tabId) { let securityInfo = await browser.webRequest.getSecurityInfo( requestId, { "certificateChain": true } ); if (securityInfo.state !== "secure" || securityInfo.isUntrusted) { await tabInsecure(tabId); return; } // Flagged as "secure" - check if CA is against any of our flagged CAs // root is last in the array cert chain let rootCA = securityInfo.certificates[securityInfo.certificates.length - 1]; for (let cert of certs) { if (rootCA.subject.includes(cert)) { await tabInsecure(tabId); return; } } await tabProbablySecure(tabId); } async function tabProbablySecure(tabId) { // only update if not already insecure let t = await browser.browserAction.getBadgeText({ tabId }); if (t === "") setIcon("ok", tabId); } async function tabInsecure(tabId) { let t = await browser.browserAction.getBadgeText({ tabId }); if (!t) setIcon("nope", tabId); let n = Number(t) + 1; browser.browserAction.setBadgeText({ text: n.toString(), tabId }); } function setIcon(icon, tabId) { browser.browserAction.setIcon({ path: "icons/" + icon + ".png", tabId: tabId }); } // Listen for all header receive events, which contain the cert details we want browser.webRequest.onHeadersReceived.addListener( onHeaderReceive, { urls: [""] }, [ "blocking" ] ); function updateCerts() { const getting = browser.storage.sync.get("certs"); getting.then(saved => { certs = saved.certs; console.log("certs=" + certs) }, console.error) } // Listen to config change for certs list browser.storage.local.onChanged.addListener(() => updateCerts()); // Initial config fetch updateCerts();