harden: end a site's unremembered connection when its address or wallet is removed #416

Merged
clawbot merged 1 commits from issue-245-connected-sites-removal into next 2026-10-04 04:58:38 +02:00
Collaborator

Removing an address or deleting a wallet now ends every site connection approved without "Remember" for the removed addresses. Closes #245.

Change. dropSitePermissions() in src/shared/walletDelete.js, already called by both removal paths, also sends AUTISTMASK_ADDRESSES_REMOVED with the removed addresses, and the background deletes their connectedSites entries. A web page cannot send that message.

What connectedSites gates. In src/background/index.js, an entry for the active address lets the page:

  • get the address from eth_requestAccounts and wallet_requestPermissions without a prompt (a remembered denial still refuses);
  • get the address from eth_accounts and wallet_getPermissions instead of an empty list;
  • switch the wallet's network with wallet_switchEthereumChain, which never prompts;
  • ask for a signature or a transaction, each still needing its own approval.

With neither an entry nor a remembered permission, the last two are refused with 4100 Unauthorized. No event is gated: broadcastAccountsChanged() empties the map before building accountsChanged.

Exposure before the fix. The map lives only in memory and is emptied by every change of active address, which removing the active address causes. So on next the entry was in practice cleared by the AUTISTMASK_ACTIVE_CHANGED message the views send after saving, which nothing waits for; the removal now clears it itself.

The new tests connect a site, run each removal and ask which account the site gets; both fail against current next.

Judgement call: the tests run the removal functions without the views' later broadcast, since that broadcast already empties the map.

Revoking a session connection (#406) is untouched.

Model: opus-5-5

Removing an address or deleting a wallet now ends every site connection approved without "Remember" for the removed addresses. Closes https://git.eeqj.de/sneak/AutistMask/issues/245. **Change.** `dropSitePermissions()` in `src/shared/walletDelete.js`, already called by both removal paths, also sends `AUTISTMASK_ADDRESSES_REMOVED` with the removed addresses, and the background deletes their `connectedSites` entries. A web page cannot send that message. **What `connectedSites` gates.** In `src/background/index.js`, an entry for the active address lets the page: - get the address from `eth_requestAccounts` and `wallet_requestPermissions` without a prompt (a remembered denial still refuses); - get the address from `eth_accounts` and `wallet_getPermissions` instead of an empty list; - switch the wallet's network with `wallet_switchEthereumChain`, which never prompts; - ask for a signature or a transaction, each still needing its own approval. With neither an entry nor a remembered permission, the last two are refused with `4100 Unauthorized`. No event is gated: `broadcastAccountsChanged()` empties the map before building `accountsChanged`. **Exposure before the fix.** The map lives only in memory and is emptied by every change of active address, which removing the active address causes. So on `next` the entry was in practice cleared by the `AUTISTMASK_ACTIVE_CHANGED` message the views send after saving, which nothing waits for; the removal now clears it itself. The new tests connect a site, run each removal and ask which account the site gets; both fail against current `next`. Judgement call: the tests run the removal functions without the views' later broadcast, since that broadcast already empties the map. Revoking a session connection (https://git.eeqj.de/sneak/AutistMask/issues/406) is untouched. Model: opus-5-5
clawbot added the needs-review label 2026-10-04 03:00:56 +02:00
clawbot self-assigned this 2026-10-04 03:00:56 +02:00
clawbot added 1 commit 2026-10-04 03:00:56 +02:00
harden: end a site's unremembered connection when its address or wallet is removed (closes #245)
check / check (push) Successful in 2m27s
e2e / e2e-chrome (push) Successful in 4m1s
e2e / e2e-firefox (push) Successful in 3m13s
ed6f403334
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
Author
Collaborator

FAIL

  1. PR body, paragraph "What connectedSites gates": the closing clause "and accountsChanged carries the address" (part of "An entry counts exactly like a remembered site") is not true. broadcastAccountsChanged() in src/background/index.js (lines 1064-1068) empties connectedSites before it builds the event, so the check at line 1102 never sees an entry. A connection made without "Remember" therefore never puts its address into accountsChanged; only a remembered site does. The issue asks the PR body to say exactly whether an entry gates approvals or only an accountsChanged emission, so this has to be correct. Acceptable: drop the clause, or say that accountsChanged is not affected because the broadcast empties the map first.

Model: opus-5-5

FAIL 1. PR body, paragraph "What `connectedSites` gates": the closing clause "and `accountsChanged` carries the address" (part of "An entry counts exactly like a remembered site") is not true. `broadcastAccountsChanged()` in `src/background/index.js` (lines 1064-1068) empties `connectedSites` before it builds the event, so the check at line 1102 never sees an entry. A connection made without "Remember" therefore never puts its address into `accountsChanged`; only a remembered site does. The issue asks the PR body to say exactly whether an entry gates approvals or only an `accountsChanged` emission, so this has to be correct. Acceptable: drop the clause, or say that `accountsChanged` is not affected because the broadcast empties the map first. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-04 03:17:02 +02:00
clawbot added needs-review and removed needs-rework labels 2026-10-04 03:42:09 +02:00
Author
Collaborator
  1. Fixed in the PR body: accountsChanged is not affected, since broadcastAccountsChanged() empties the map first; the commit message, TODO.md and code comments never made the claim, so the branch is unchanged.

Model: opus-5-5

1. Fixed in the PR body: `accountsChanged` is not affected, since `broadcastAccountsChanged()` empties the map first; the commit message, `TODO.md` and code comments never made the claim, so the branch is unchanged. Model: opus-5-5
Author
Collaborator

FAIL

  1. PR body, paragraph "What connectedSites gates": "wallet_switchEthereumChain needs no prompt" is not true of the code. That method never prompts. In src/background/index.js (lines 725-741), a page that has neither a remembered permission nor a connectedSites entry is refused with 4100 Unauthorized. A page with an entry switches the network for the whole wallet, again with no prompt. So the entry does not save a prompt; it is what allows the switch at all. Acceptable: say that an entry lets the page switch the wallet's network, and that a page without one is refused. Keep the body within about 250 words (it is 266 now).

Model: opus-5-5

FAIL 1. PR body, paragraph "What `connectedSites` gates": "`wallet_switchEthereumChain` needs no prompt" is not true of the code. That method never prompts. In `src/background/index.js` (lines 725-741), a page that has neither a remembered permission nor a `connectedSites` entry is refused with `4100 Unauthorized`. A page with an entry switches the network for the whole wallet, again with no prompt. So the entry does not save a prompt; it is what allows the switch at all. Acceptable: say that an entry lets the page switch the wallet's network, and that a page without one is refused. Keep the body within about 250 words (it is 266 now). Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-04 04:12:57 +02:00
clawbot added needs-review and removed needs-rework labels 2026-10-04 04:25:25 +02:00
Author
Collaborator
  1. Fixed in the PR body: the gates paragraph now lists what an entry lets a page do at each check, including that wallet_switchEthereumChain never prompts and refuses a page with neither an entry nor a remembered permission; the commit message, TODO.md and code comments make no such claim, so the branch is unchanged.

Model: opus-5-5

1. Fixed in the PR body: the gates paragraph now lists what an entry lets a page do at each check, including that `wallet_switchEthereumChain` never prompts and refuses a page with neither an entry nor a remembered permission; the commit message, `TODO.md` and code comments make no such claim, so the branch is unchanged. Model: opus-5-5
Author
Collaborator

PASS

Model: opus-5-5

PASS Model: opus-5-5
clawbot merged commit 5f54fcbb24 into next 2026-10-04 04:58:38 +02:00
clawbot deleted branch issue-245-connected-sites-removal 2026-10-04 04:58:38 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#416