mirror of
https://github.com/DarrylNixon/CrowdTLS
synced 2024-04-22 06:17:20 -07:00
Add per-tab processing of multiple certs
This commit is contained in:
parent
359c35a04e
commit
396ba90c7e
1 changed files with 52 additions and 23 deletions
73
worker.js
73
worker.js
|
@ -10,6 +10,8 @@
|
|||
// const API_BASE = "https://crowdtls.mips.uk/api/v1";
|
||||
const API_BASE = "http://127.0.0.1:8000/api/v1";
|
||||
|
||||
let send_buffer = {};
|
||||
|
||||
/**
|
||||
* Processes the given request details to extract and log security information.
|
||||
*
|
||||
|
@ -26,6 +28,7 @@ async function process_request(details) {
|
|||
let securityInfo = await browser.webRequest.getSecurityInfo(details.requestId, { certificateChain: true, rawDER: true });
|
||||
if (securityInfo.state !== "insecure") {
|
||||
const fingerprint = securityInfo.certificates[0].fingerprint.sha256;
|
||||
|
||||
let fpData = localStorage.getItem(fingerprint);
|
||||
|
||||
const currentTime = Date.now();
|
||||
|
@ -46,7 +49,17 @@ async function process_request(details) {
|
|||
fpData.lastCheck = currentTime;
|
||||
localStorage.setItem(fingerprint, JSON.stringify(fpData));
|
||||
|
||||
await check_fingerprint(hostname, securityInfo.certificates);
|
||||
const tab = details.tabId;
|
||||
if (!send_buffer[tab]) {
|
||||
send_buffer[tab] = {};
|
||||
}
|
||||
if (!send_buffer[tab][hostname]) {
|
||||
send_buffer[tab][hostname] = {};
|
||||
}
|
||||
|
||||
securityInfo.certificates.forEach(cert => {
|
||||
send_buffer[tab][hostname][cert.fingerprint.sha256] = cert.rawDER;
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
@ -59,17 +72,19 @@ async function process_request(details) {
|
|||
*
|
||||
* @async
|
||||
* @function
|
||||
* @param {string} hostname - The hostname of the website.
|
||||
* @param {Array} certificates - The list of certificates.
|
||||
* @param {Object} buffer - The buffer containing info for a specific tab
|
||||
*/
|
||||
async function check_fingerprint(hostname, certificates) {
|
||||
try {
|
||||
const fingerprints = certificates.map(cert => cert.fingerprint.sha256);
|
||||
async function do_checks(buffer) {
|
||||
let fingerprint_buffer = {};
|
||||
Object.keys(buffer).forEach(hostname => {
|
||||
fingerprint_buffer[hostname] = Object.keys(buffer[hostname]);
|
||||
});
|
||||
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/check`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ host: hostname, fps: fingerprints }),
|
||||
body: JSON.stringify(fingerprint_buffer),
|
||||
timeout: 5000
|
||||
});
|
||||
|
||||
|
@ -80,11 +95,12 @@ async function check_fingerprint(hostname, certificates) {
|
|||
|
||||
const data = await response.json();
|
||||
|
||||
if (data) {
|
||||
if (data["send"] === true) {
|
||||
send_certificate_chain(hostname, certificates);
|
||||
}
|
||||
Object.keys(buffer).forEach(hostname => {
|
||||
if (!data[hostname]) {
|
||||
delete buffer[hostname];
|
||||
}
|
||||
});
|
||||
send_certificate_chain(buffer);
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
|
@ -96,23 +112,17 @@ async function check_fingerprint(hostname, certificates) {
|
|||
*
|
||||
* @async
|
||||
* @function
|
||||
* @param {string} hostname - The hostname of the website.
|
||||
* @param {Array} certificates - The list of certificates.
|
||||
* @param {Object} chain - The buffer containing info for a specific tab
|
||||
* @throws Will log an error to the console if the request fails.
|
||||
*/
|
||||
async function send_certificate_chain(hostname, certificates) {
|
||||
async function send_certificate_chain(chain) {
|
||||
try {
|
||||
let chain = {};
|
||||
certificates.forEach(cert => {
|
||||
chain[cert.fingerprint.sha256] = cert.rawDER;
|
||||
});
|
||||
|
||||
const response = await fetch(`${API_BASE}/new`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ host: hostname, certs: chain }),
|
||||
body: JSON.stringify(chain),
|
||||
timeout: 10000
|
||||
});
|
||||
|
||||
|
@ -125,11 +135,13 @@ async function send_certificate_chain(hostname, certificates) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Performs garbage collection on localStorage by removing objects older than 12 hours based on their "lastCheck" property,
|
||||
* and removes entries from send_buffer if that tab ID is no longer open.
|
||||
*
|
||||
* @function
|
||||
* @description Performs garbage collection on localStorage by removing objects older than 12 hours based on their "lastCheck" property.
|
||||
* @returns {void}
|
||||
*/
|
||||
function garbage_collection() {
|
||||
async function garbage_collection() {
|
||||
const now = new Date().getTime();
|
||||
const twelveHoursInMillis = 12 * 60 * 60 * 1000;
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
|
@ -142,6 +154,15 @@ function garbage_collection() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
const tabs = await browser.tabs.query({});
|
||||
const open_tabs = tabs.map(tab => tab.id);
|
||||
|
||||
for (const tabId in send_buffer) {
|
||||
if (!open_tabs.includes(Number(tabId))) {
|
||||
delete send_buffer[tabId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setInterval(garbage_collection, 3600000);
|
||||
|
@ -158,3 +179,11 @@ browser.webRequest.onHeadersReceived.addListener(
|
|||
{ urls: ["https://*/*"] },
|
||||
["blocking"]
|
||||
);
|
||||
|
||||
// When a tab update happens (i.e., page load complete), send the buffered data
|
||||
browser.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {
|
||||
if (changeInfo.status === "complete" && send_buffer[tabId]) {
|
||||
await do_checks(send_buffer[tabId]);
|
||||
delete send_buffer[tabId];
|
||||
}
|
||||
});
|
Loading…
Reference in a new issue