1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
// 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: ["<all_urls>"]
},
[
"blocking"
]
);
function updateCerts() {
const getting = browser.storage.sync.get("certs");
getting.then(saved => {
certs = saved.certs;
// Reset all tab data
browser.tabs.query({}).then(tabs => {
for (let tab of tabs) {
browser.browserAction.setIcon({ tabId: tab.id });
browser.browserAction.setBadgeText({ text: "", tabId: tab.id });
}
}, console.error);
}, console.error)
}
// Listen to config change for certs list
browser.storage.sync.onChanged.addListener(() => updateCerts());
// Initial config fetch
updateCerts();
|