mirror of
https://github.com/mdn/webextensions-examples.git
synced 2026-04-16 06:18:35 +02:00
Add an example using webRequest.getSecurityInfo() (#362)
* Add an example using webRequest.getSecurityInfo() * Don't collect root certs if isUntrusted===true
This commit is contained in:
15
root-cert-stats/README.md
Normal file
15
root-cert-stats/README.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# root-cert-stats
|
||||||
|
|
||||||
|
## What it does ##
|
||||||
|
|
||||||
|
The extension includes:
|
||||||
|
|
||||||
|
* a background page which collects stats about the trusted root certs used when
|
||||||
|
browsing the web. It records the subject name of each root cert, and how many
|
||||||
|
times that particular root cert was used to establish a TLS connection.
|
||||||
|
|
||||||
|
* a browser action with a popup. The popup displays the collected stats.
|
||||||
|
|
||||||
|
## What it shows ##
|
||||||
|
|
||||||
|
* how to use the webRequest.getSecurityInfo() API.
|
||||||
38
root-cert-stats/background.js
Normal file
38
root-cert-stats/background.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
var rootCertStats = {};
|
||||||
|
|
||||||
|
/*
|
||||||
|
On an onHeadersReceived event, if there was a successful TLS connection
|
||||||
|
established, fetch the root cert and look at its subject.
|
||||||
|
|
||||||
|
If we haven't seen this subject before, add it. If we have, increment its stats.
|
||||||
|
*/
|
||||||
|
async function logRootCert(details) {
|
||||||
|
try {
|
||||||
|
let securityInfo = await browser.webRequest.getSecurityInfo(
|
||||||
|
details.requestId,
|
||||||
|
{"certificateChain": true}
|
||||||
|
);
|
||||||
|
if ((securityInfo.state == "secure" || securityInfo.state == "weak") &&
|
||||||
|
!securityInfo.isUntrusted) {
|
||||||
|
let rootName = securityInfo.certificates[securityInfo.certificates.length - 1].subject;
|
||||||
|
if (rootCertStats[rootName] === undefined) {
|
||||||
|
rootCertStats[rootName] = 1;
|
||||||
|
} else {
|
||||||
|
rootCertStats[rootName] = rootCertStats[rootName] + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Listen for all onHeadersReceived events.
|
||||||
|
*/
|
||||||
|
browser.webRequest.onHeadersReceived.addListener(logRootCert,
|
||||||
|
{urls: ["<all_urls>"]},
|
||||||
|
["blocking"]
|
||||||
|
);
|
||||||
1
root-cert-stats/icons/LICENSE
Normal file
1
root-cert-stats/icons/LICENSE
Normal file
@@ -0,0 +1 @@
|
|||||||
|
The icon "icon-32.png" is taken from the IconBeast Lite iconset, and used under the terms of its license (http://www.iconbeast.com/faq/), with a link back to the website: http://www.iconbeast.com/free/.
|
||||||
BIN
root-cert-stats/icons/icon-32.png
Normal file
BIN
root-cert-stats/icons/icon-32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 259 B |
25
root-cert-stats/manifest.json
Normal file
25
root-cert-stats/manifest.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"manifest_version": 2,
|
||||||
|
"name": "Root Certificate Stats",
|
||||||
|
"description": "Track and display which CA root certificates are used and how often.",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"browser_action": {
|
||||||
|
"default_icon": {
|
||||||
|
"32": "icons/icon-32.png"
|
||||||
|
},
|
||||||
|
"default_title": "Root Certificate Stats",
|
||||||
|
"default_popup": "popup.html"
|
||||||
|
},
|
||||||
|
"permissions": ["webRequest", "webRequestBlocking", "<all_urls>"],
|
||||||
|
"background": {
|
||||||
|
"scripts": [ "background.js" ]
|
||||||
|
},
|
||||||
|
"icons": {
|
||||||
|
"32": "icons/icon-32.png"
|
||||||
|
},
|
||||||
|
"applications": {
|
||||||
|
"gecko": {
|
||||||
|
"strict_min_version": "62.0b5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
root-cert-stats/popup.css
Normal file
13
root-cert-stats/popup.css
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
body {
|
||||||
|
font: 1rem/2 sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
table,
|
||||||
|
td {
|
||||||
|
border: 1px solid #333;
|
||||||
|
padding: .3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
21
root-cert-stats/popup.html
Normal file
21
root-cert-stats/popup.html
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<link rel="stylesheet" href="popup.css"/>
|
||||||
|
<title>Root cert stats</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="no-data">No data to display yet</div>
|
||||||
|
<table class="root-cert-table hidden">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th colspan="2">Certification Authorities</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
<script src="popup.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
33
root-cert-stats/popup.js
Normal file
33
root-cert-stats/popup.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get the background page to access the rootCertStats object
|
||||||
|
*/
|
||||||
|
const backgroundPage = browser.extension.getBackgroundPage();
|
||||||
|
|
||||||
|
let entries = Object.keys(backgroundPage.rootCertStats);
|
||||||
|
|
||||||
|
/*
|
||||||
|
If there are any stats, show the table, and append one row for each entry.
|
||||||
|
Each row contains the name of the CA and the number of times it has been
|
||||||
|
used as a trust root.
|
||||||
|
*/
|
||||||
|
if (entries.length > 0) {
|
||||||
|
|
||||||
|
let noData = document.querySelector(".no-data");
|
||||||
|
noData.classList.add("hidden");
|
||||||
|
let entryTable = document.querySelector(".root-cert-table");
|
||||||
|
entryTable.classList.remove("hidden");
|
||||||
|
|
||||||
|
for (let entry of entries) {
|
||||||
|
let entryTR = document.createElement("tr");
|
||||||
|
let entryName = document.createElement("td");
|
||||||
|
let entryValue = document.createElement("td");
|
||||||
|
entryName.textContent = entry;
|
||||||
|
entryValue.textContent = backgroundPage.rootCertStats[entry];
|
||||||
|
|
||||||
|
entryTR.appendChild(entryName);
|
||||||
|
entryTR.appendChild(entryValue);
|
||||||
|
entryTable.appendChild(entryTR);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user