harden: end a site's unremembered connection when its address or wallet is removed (closes #245)
check / check (push) Successful in 1m34s
e2e / e2e-chrome (push) Successful in 2m1s
e2e / e2e-firefox (push) Successful in 36s

A site connected without "Remember" lives only in the background's
in-memory connectedSites map. Removing an address or deleting a wallet
dropped the remembered permissions but never told the background; the
entry went only as a side effect of the accountsChanged broadcast, which
empties the whole map when the active address changes.

dropSitePermissions(), shared by both removal paths, now sends
AUTISTMASK_ADDRESSES_REMOVED with the removed addresses, and the
background deletes their entries. Only the extension's own pages may
send it.

Model: opus-5-5
This commit was merged in pull request #416.
This commit is contained in:
2026-10-04 04:58:38 +02:00
parent 00d6193ee7
commit 5f54fcbb24
6 changed files with 141 additions and 3 deletions
+15
View File
@@ -1305,6 +1305,7 @@ runtime.onMessage.addListener((msg, sender, sendResponse) => {
"AUTISTMASK_GET_APPROVAL",
"AUTISTMASK_TX_RESPONSE",
"AUTISTMASK_SIGN_RESPONSE",
"AUTISTMASK_ADDRESSES_REMOVED",
];
if (POPUP_ONLY_TYPES.includes(msg.type) && !isExtensionSender(sender)) {
sendResponse({ error: "Unauthorized sender" });
@@ -1647,6 +1648,20 @@ runtime.onMessage.addListener((msg, sender, sendResponse) => {
return false;
}
// The popup removed these addresses, so no site stays connected to them.
// A connectedSites key is origin + ":" + address, and an origin can carry
// a port, so the address is what follows the last colon.
if (msg.type === "AUTISTMASK_ADDRESSES_REMOVED") {
const removed = Array.isArray(msg.addresses) ? msg.addresses : [];
for (const key of Object.keys(connectedSites)) {
const address = key.slice(key.lastIndexOf(":") + 1);
if (removed.some((a) => sameAddress(a, address))) {
delete connectedSites[key];
}
}
return false;
}
if (msg.type === "AUTISTMASK_REMOVE_SITE") {
// Popup already saved state; nothing else needed
return false;