security: replace predictable sequential approval IDs with crypto.randomUUID()

This commit is contained in:
2026-02-27 11:34:48 -08:00
parent 1237cf8491
commit 95314ff229

View File

@@ -30,7 +30,6 @@ const connectedSites = {};
// Pending approval requests: { id: { origin, hostname, resolve } }
const pendingApprovals = {};
let nextApprovalId = 1;
async function getState() {
const result = await storageApi.get("autistmask");
@@ -127,7 +126,7 @@ function openApprovalWindow(id) {
// Prefers the browser-action popup (anchored to toolbar, no macOS Space switch).
function requestApproval(origin, hostname) {
return new Promise((resolve) => {
const id = nextApprovalId++;
const id = crypto.randomUUID();
pendingApprovals[id] = { origin, hostname, resolve };
if (actionApi && typeof actionApi.openPopup === "function") {
@@ -152,7 +151,7 @@ function requestApproval(origin, hostname) {
// Uses the toolbar popup only — no fallback window.
function requestTxApproval(origin, hostname, txParams) {
return new Promise((resolve) => {
const id = nextApprovalId++;
const id = crypto.randomUUID();
pendingApprovals[id] = {
origin,
hostname,
@@ -184,7 +183,7 @@ function requestTxApproval(origin, hostname, txParams) {
// popup URL is still set, so the user can click the toolbar icon to respond.
function requestSignApproval(origin, hostname, signParams) {
return new Promise((resolve) => {
const id = nextApprovalId++;
const id = crypto.randomUUID();
pendingApprovals[id] = {
origin,
hostname,
@@ -216,7 +215,7 @@ function requestSignApproval(origin, hostname, signParams) {
// popups naturally close on focus loss and the user can reopen them.
runtime.onConnect.addListener((port) => {
if (port.name.startsWith("approval:")) {
const id = parseInt(port.name.split(":")[1], 10);
const id = port.name.split(":")[1];
port.onDisconnect.addListener(() => {
const approval = pendingApprovals[id];
if (approval) {