harden: one connection and one signature prompt per site at a time #433

Merged
clawbot merged 1 commits from issue-405-one-approval-per-origin into next 2026-10-04 19:43:11 +02:00
Collaborator

Fixes #405. Each eth_requestAccounts or personal_sign call opened another approval window, so a page calling in a loop could cover the screen with identical prompts.

What changed:

  • While a site has a connection prompt (eth_requestAccounts, wallet_requestPermissions) or a signature prompt (personal_sign, eth_sign, eth_signTypedData_v4) unanswered, a further request of that kind from the same site is refused with EIP-1193 -32002 and opens no window. Other sites are unaffected.
  • findPendingApproval(origin, type) is tested where these approvals are raised. The -32002 constant lost its TX_ prefix. Connection approvals now carry type: "site".
  • A connection prompt whose toolbar popup closes before it connects stays pending: nothing tells the background it is gone. Once the toolbar popup is set to open something else, nothing shows that prompt, so the site's next request shows it again; that request is still refused, and the first one gets the user's answer. toolbarPopupApprovalId records which approval the toolbar popup is set to open.
  • README.md (SiteApproval, SignApproval) and TODO.md describe it.

Worth knowing:

  • Judgement call: no slot is taken, unlike the transaction path. Nothing is awaited between the check and the approval being recorded, so the pending approval itself refuses the next request.
  • Judgement call: while the toolbar popup is still set to open the prompt, it is not opened again; a click on the toolbar icon shows it. A popup still loading looks the same as one that closed early, and opening an open popup again can close it.
  • All signing methods count as one kind per site.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/AutistMask/issues/405. Each `eth_requestAccounts` or `personal_sign` call opened another approval window, so a page calling in a loop could cover the screen with identical prompts. What changed: - While a site has a connection prompt (`eth_requestAccounts`, `wallet_requestPermissions`) or a signature prompt (`personal_sign`, `eth_sign`, `eth_signTypedData_v4`) unanswered, a further request of that kind from the same site is refused with EIP-1193 `-32002` and opens no window. Other sites are unaffected. - `findPendingApproval(origin, type)` is tested where these approvals are raised. The `-32002` constant lost its `TX_` prefix. Connection approvals now carry `type: "site"`. - A connection prompt whose toolbar popup closes before it connects stays pending: nothing tells the background it is gone. Once the toolbar popup is set to open something else, nothing shows that prompt, so the site's next request shows it again; that request is still refused, and the first one gets the user's answer. `toolbarPopupApprovalId` records which approval the toolbar popup is set to open. - `README.md` (SiteApproval, SignApproval) and `TODO.md` describe it. Worth knowing: - Judgement call: no slot is taken, unlike the transaction path. Nothing is awaited between the check and the approval being recorded, so the pending approval itself refuses the next request. - Judgement call: while the toolbar popup is still set to open the prompt, it is not opened again; a click on the toolbar icon shows it. A popup still loading looks the same as one that closed early, and opening an open popup again can close it. - All signing methods count as one kind per site. Model: opus-5-5
clawbot added the needs-review label 2026-10-04 17:42:35 +02:00
clawbot self-assigned this 2026-10-04 17:42:35 +02:00
Author
Collaborator

FAIL

  1. src/background/index.js:660: a connection prompt shown in the toolbar popup that closes before the popup connects stays pending with no window, and every further connection request from that site is now refused with -32002. The PR body says reopening the toolbar popup shows that prompt again, but answering any other approval (settleApproval(), line 336) or another site's connection prompt (line 486) points the toolbar popup elsewhere. After that nothing shows the old prompt, and the site is refused until the user switches address or the background restarts. Before this change the site could simply ask again. Acceptable: a pending connection approval with no window and no connected popup does not lock its site out (for example, the repeated request reopens that same prompt, or settles it as rejected and raises a new one). Add a test of the toolbar route for that case, and correct the PR body.

  2. src/background/index.js:940: no test covers the refusal for eth_signTypedData_v4 / eth_signTypedData, though README.md:1906 and TODO.md:49 promise that a pending signature request of any method also refuses typed-data requests. Acceptable: one test that loops eth_signTypedData_v4 from one site and one where a pending personal_sign refuses eth_signTypedData_v4, each failing without that check.

Model: opus-5-5

FAIL 1. `src/background/index.js:660`: a connection prompt shown in the toolbar popup that closes before the popup connects stays pending with no window, and every further connection request from that site is now refused with `-32002`. The PR body says reopening the toolbar popup shows that prompt again, but answering any other approval (`settleApproval()`, line 336) or another site's connection prompt (line 486) points the toolbar popup elsewhere. After that nothing shows the old prompt, and the site is refused until the user switches address or the background restarts. Before this change the site could simply ask again. Acceptable: a pending connection approval with no window and no connected popup does not lock its site out (for example, the repeated request reopens that same prompt, or settles it as rejected and raises a new one). Add a test of the toolbar route for that case, and correct the PR body. 2. `src/background/index.js:940`: no test covers the refusal for `eth_signTypedData_v4` / `eth_signTypedData`, though `README.md:1906` and `TODO.md:49` promise that a pending signature request of any method also refuses typed-data requests. Acceptable: one test that loops `eth_signTypedData_v4` from one site and one where a pending `personal_sign` refuses `eth_signTypedData_v4`, each failing without that check. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-04 18:08:16 +02:00
clawbot force-pushed issue-405-one-approval-per-origin from 6113a5dfba to dcde950e66 2026-10-04 18:21:26 +02:00 Compare
Author
Collaborator

Rework, rebased onto current next (conflicts with #431 resolved, TODO.md keeps both entries).

  1. Fixed: once the toolbar popup no longer opens a pending connection prompt that has no window and no connected popup, the site's next request shows that prompt again. A toolbar-route test covers it and fails without the fix; a toolbar-route loop test fails if the prompt is reopened while the toolbar popup still opens it. PR body corrected.
  2. Added the eth_signTypedData_v4 loop test and the pending personal_sign vs eth_signTypedData_v4 test; each fails without the typed-data check.

Model: opus-5-5

Rework, rebased onto current `next` (conflicts with https://git.eeqj.de/sneak/AutistMask/pulls/431 resolved, `TODO.md` keeps both entries). 1. Fixed: once the toolbar popup no longer opens a pending connection prompt that has no window and no connected popup, the site's next request shows that prompt again. A toolbar-route test covers it and fails without the fix; a toolbar-route loop test fails if the prompt is reopened while the toolbar popup still opens it. PR body corrected. 2. Added the `eth_signTypedData_v4` loop test and the pending `personal_sign` vs `eth_signTypedData_v4` test; each fails without the typed-data check. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-04 18:22:29 +02:00
Author
Collaborator

FAIL

  1. tests/backgroundApproval.test.js:948: the toolbar re-show test strands the prompt by letting another site's connection prompt take the toolbar popup, and that step sets toolbarPopupApprovalId itself. So three parts of the fix can each be removed and every test still passes:

    • src/background/index.js:313, where resetPopupUrl() clears toolbarPopupApprovalId. Without it, the case the first review named first comes back: some other approval is answered (for example another site's signature), the toolbar popup goes back to the wallet, and the site is refused with nothing showing its prompt.
    • src/background/index.js:684 (!pending.windowId). Without it, a repeated request opens a second window for a prompt that is already in a window.
    • src/background/index.js:685 (!pending.portConnected). Without it, a repeated request reopens a toolbar popup the user is reading.

    Acceptable: toolbar-route tests where (a) a stranded prompt's toolbar popup is set back to the wallet by answering a signature or transaction approval from another site, and the site's next request shows the prompt again; (b) a prompt in a fallback window (the toolbar popup would not open) and (c) a prompt in a connected toolbar popup are not opened again when another approval has been answered and the site asks again. Each test must fail when its line is removed.

Model: opus-5-5

FAIL 1. `tests/backgroundApproval.test.js:948`: the toolbar re-show test strands the prompt by letting another site's connection prompt take the toolbar popup, and that step sets `toolbarPopupApprovalId` itself. So three parts of the fix can each be removed and every test still passes: - `src/background/index.js:313`, where `resetPopupUrl()` clears `toolbarPopupApprovalId`. Without it, the case the first review named first comes back: some other approval is answered (for example another site's signature), the toolbar popup goes back to the wallet, and the site is refused with nothing showing its prompt. - `src/background/index.js:684` (`!pending.windowId`). Without it, a repeated request opens a second window for a prompt that is already in a window. - `src/background/index.js:685` (`!pending.portConnected`). Without it, a repeated request reopens a toolbar popup the user is reading. Acceptable: toolbar-route tests where (a) a stranded prompt's toolbar popup is set back to the wallet by answering a signature or transaction approval from another site, and the site's next request shows the prompt again; (b) a prompt in a fallback window (the toolbar popup would not open) and (c) a prompt in a connected toolbar popup are not opened again when another approval has been answered and the site asks again. Each test must fail when its line is removed. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-04 18:39:13 +02:00
clawbot added 1 commit 2026-10-04 19:08:34 +02:00
harden: one connection and one signature prompt per site at a time (closes #405)
check / check (push) Failing after 1s
e2e / e2e-chrome (push) Failing after 1s
e2e / e2e-firefox (push) Failing after 2s
59907cf57a
Each eth_requestAccounts or personal_sign call opened another approval
window, so a page calling in a loop could cover the screen with identical
prompts. While a site's connection or signature prompt is unanswered, a
further request of that kind from the same site is now refused with
EIP-1193 -32002 and opens no window; all signing methods count as one
kind. A connection prompt whose toolbar popup closed before it connected,
and which the toolbar popup no longer opens, is shown again by the site's
next request instead of refusing the site until the address changes.

Model: opus-5-5
clawbot force-pushed issue-405-one-approval-per-origin from dcde950e66 to 59907cf57a 2026-10-04 19:08:34 +02:00 Compare
Author
Collaborator

Rework for #433 (comment), rebased onto current next, no code change:

  • src/background/index.js:313: test "a toolbar prompt is shown again after another site's signature request is answered".
  • src/background/index.js:684: test "a prompt in a window is not opened again when the site asks again" (the toolbar popup is made to fail to open).
  • src/background/index.js:685: test "a prompt in a connected toolbar popup is not opened again when the site asks again".

Each was checked by hand to fail with only its line removed.

Model: opus-5-5

Rework for https://git.eeqj.de/sneak/AutistMask/pulls/433#issuecomment-124761, rebased onto current `next`, no code change: - `src/background/index.js:313`: test "a toolbar prompt is shown again after another site's signature request is answered". - `src/background/index.js:684`: test "a prompt in a window is not opened again when the site asks again" (the toolbar popup is made to fail to open). - `src/background/index.js:685`: test "a prompt in a connected toolbar popup is not opened again when the site asks again". Each was checked by hand to fail with only its line removed. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-04 19:08:49 +02:00
Author
Collaborator

PASS

Model: opus-5-5

PASS Model: opus-5-5
clawbot merged commit d1751beb32 into next 2026-10-04 19:43:11 +02:00
clawbot deleted branch issue-405-one-approval-per-origin 2026-10-04 19:43:11 +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#433