decision: a connected site can switch the wallet's network with no prompt #408

Closed
opened 2026-09-21 20:37:56 +02:00 by clawbot · 4 comments
Collaborator

Severity: hardening. Owner decision.

Where. src/background/index.js:725-772 (wallet_switchEthereumChain, gated
on connection only).

The behaviour. wallet_switchEthereumChain is gated on the site being
connected, then rewrites networkId, rpcUrl and blockscoutUrl, clears
balances and caches, and broadcasts chainChanged to every tab — with no user
confirmation. The README (TxApproval section) documents the connection gate as
the fix for an unconnected page clearing the [TESTNET] banner, but a connected
site can still flip the network silently between the two supported chains.

The question. Should a chain switch require a prompt? A connected dApp moving
the user from Sepolia to mainnet (or back) before a send is silent; the send
screen does show the network, but the user may not re-read it.

Options.

  • Prompt on every wallet_switchEthereumChain, as other wallets do.
  • Keep it promptless and make the switch conspicuous on the next approval screen.

Recommendation. Keep it promptless for the two supported chains but surface
the active network prominently on the very next approval; a prompt on every
switch is friction for a wallet that supports only mainnet and one testnet.

Definition of done.

  • The owner rules prompt vs promptless.
  • The chosen behaviour is implemented and the README matches it.

Model: fable-5-1 (review); opus-4-8 (filing)

Severity: hardening. Owner decision. **Where.** `src/background/index.js:725-772` (`wallet_switchEthereumChain`, gated on connection only). **The behaviour.** `wallet_switchEthereumChain` is gated on the site being connected, then rewrites `networkId`, `rpcUrl` and `blockscoutUrl`, clears balances and caches, and broadcasts `chainChanged` to every tab — with no user confirmation. The README (TxApproval section) documents the connection gate as the fix for an unconnected page clearing the `[TESTNET]` banner, but a connected site can still flip the network silently between the two supported chains. **The question.** Should a chain switch require a prompt? A connected dApp moving the user from Sepolia to mainnet (or back) before a send is silent; the send screen does show the network, but the user may not re-read it. **Options.** - Prompt on every `wallet_switchEthereumChain`, as other wallets do. - Keep it promptless and make the switch conspicuous on the next approval screen. **Recommendation.** Keep it promptless for the two supported chains but surface the active network prominently on the very next approval; a prompt on every switch is friction for a wallet that supports only mainnet and one testnet. **Definition of done.** - [ ] The owner rules prompt vs promptless. - [ ] The chosen behaviour is implemented and the README matches it. Model: fable-5-1 (review); opus-4-8 (filing)
sneak was assigned by clawbot 2026-09-21 20:37:56 +02:00
Owner

obviously a critical security bug. switching networks MUST be done by a user.

obviously a critical security bug. switching networks MUST be done by a user.
Author
Collaborator

Ruling (sneak, 2026-10-07, above): this is a critical security bug. Only the user switches the wallet's network; a connected site's wallet_switchEthereumChain request must never change it on its own.

Labelled critical and reassigned to clawbot, ahead of other work in this repo. Definition of done:

  • No request from a site changes networkId, rpcUrl or blockscoutUrl, clears balances or broadcasts chainChanged unless the user has switched the network himself in that moment (either by approving that request on a prompt, or in Settings with the request refused); the PR says which and why.
  • A test, failing first, shows a connected site's switch request leaves the network unchanged without the user's action.
  • The README's TxApproval section describes the new behaviour.
  • Lands on next as one reviewed PR.

Model: opus-5-5

Ruling (sneak, 2026-10-07, above): this is a critical security bug. Only the user switches the wallet's network; a connected site's `wallet_switchEthereumChain` request must never change it on its own. Labelled `critical` and reassigned to clawbot, ahead of other work in this repo. Definition of done: - No request from a site changes `networkId`, `rpcUrl` or `blockscoutUrl`, clears balances or broadcasts `chainChanged` unless the user has switched the network himself in that moment (either by approving that request on a prompt, or in Settings with the request refused); the PR says which and why. - A test, failing first, shows a connected site's switch request leaves the network unchanged without the user's action. - The README's TxApproval section describes the new behaviour. - Lands on `next` as one reviewed PR. Model: opus-5-5
sneak was unassigned by clawbot 2026-10-07 23:17:44 +02:00
clawbot self-assigned this 2026-10-07 23:17:44 +02:00
clawbot added the critical label 2026-10-07 23:17:44 +02:00
Author
Collaborator

Plan: first list every path by which a page can change the network, then close each. A site's switch request opens a confirmation prompt through the existing approval windows and changes the network only when the user approves; rejecting returns the user-rejected error. If a prompt would need new machinery, the request is refused and the user switches in Settings; the PR says which. Tests fail first on next.

Model: opus-5-5

Plan: first list every path by which a page can change the network, then close each. A site's switch request opens a confirmation prompt through the existing approval windows and changes the network only when the user approves; rejecting returns the user-rejected error. If a prompt would need new machinery, the request is refused and the user switches in Settings; the PR says which. Tests fail first on `next`. Model: opus-5-5
Author
Collaborator

Built on #501.

Only the user switches the network now. A connected site's wallet_switchEthereumChain request for the other supported network opens a prompt in its own window, through the same approval machinery as the transaction and signature prompts, naming the site, the current network and the requested one. Nothing changes until the user approves it there: not networkId, rpcUrl or blockscoutUrl, not the balances or caches, and no chainChanged goes out. Rejecting or closing the prompt answers the site with 4001. A request for the network already active changes nothing and opens no prompt; an unsupported chain still gets 4902, an unconnected site 4100. wallet_switchEthereumChain was the only path by which a page could change the network; the PR lists the others that were checked.

The README's TxApproval and Settings sections describe it, and a new NetworkApproval section describes the prompt. Tests fail first on next; the prompt is driven in both browser suites.

Found alongside and filed separately: #500.

Model: opus-5-5 (implementation); fable-5-1 (comment)

Built on https://git.eeqj.de/sneak/AutistMask/pulls/501. Only the user switches the network now. A connected site's `wallet_switchEthereumChain` request for the other supported network opens a prompt in its own window, through the same approval machinery as the transaction and signature prompts, naming the site, the current network and the requested one. Nothing changes until the user approves it there: not `networkId`, `rpcUrl` or `blockscoutUrl`, not the balances or caches, and no `chainChanged` goes out. Rejecting or closing the prompt answers the site with 4001. A request for the network already active changes nothing and opens no prompt; an unsupported chain still gets 4902, an unconnected site 4100. `wallet_switchEthereumChain` was the only path by which a page could change the network; the PR lists the others that were checked. The README's TxApproval and Settings sections describe it, and a new NetworkApproval section describes the prompt. Tests fail first on `next`; the prompt is driven in both browser suites. Found alongside and filed separately: https://git.eeqj.de/sneak/AutistMask/issues/500. Model: opus-5-5 (implementation); fable-5-1 (comment)
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#408