test: drive the EIP-1193 dApp approval round trips in the browser (closes #183)
All checks were successful
check / check (push) Successful in 29s

The dApp signing path was the largest unverified surface in the milestone: the
only place where the content script, the inpage provider, the background worker
and the popup all have to work together, with unit tests covering each side in
isolation and none covering the seam.

A page served by the harness speaks EIP-1193 to the real provider -- asserted by
EIP-6963 object identity, not by shape -- and eth_requestAccounts, personal_sign,
eth_signTypedData_v4 and eth_sendTransaction are each driven through to approval
and to rejection.

Every signature is recovered and compared to the approved address; the broadcast
transaction is parsed from the bytes captured at eth_sendRawTransaction and
checked for signer, recipient, value, calldata and chain. A signature that
merely came back would pass against a wrong key, a wrong message or a wrong
chain, so each assertion was demonstrated failing against a variant that is
wrong in exactly one of those ways.

The password is asserted absent from every message crossing the extension
boundary, which gives #157's fix a permanent floor rather than a one-time
review.

Two defects this surfaced are tracked separately: EIP-1193 error codes never
reach the page (#274), and approving a site connection races the popup teardown
(#275). Neither is asserted as correct here. A real dApp with real funds against
mainnet remains an uncovered human pass and is documented as such.
This commit was merged in pull request #273.
This commit is contained in:
2026-08-12 13:23:57 +02:00
parent e4c3708b84
commit d5595c0151
4 changed files with 1150 additions and 1 deletions

11
TODO.md
View File

@@ -45,6 +45,17 @@ undefined identifiers, which is how
# Completed Steps
- 2026-08-12: The dApp approval round trips are driven end to end in the
browser. A test page served by the harness speaks EIP-1193 to the real inpage
provider through the real content script, background worker and approval popup
for `eth_requestAccounts`, `personal_sign`, `eth_signTypedData_v4` and
`eth_sendTransaction`. Every signature is recovered and compared against the
active address, the transaction is checked against the bytes handed to the
stubbed RPC, each rejection must reach the page as a rejection, and the
password must appear in no message the approval window sends — the assertion
that gives [#157](https://git.eeqj.de/sneak/AutistMask/issues/157) a permanent
floor. This does not discharge a real dApp with real funds against mainnet
([#183](https://git.eeqj.de/sneak/AutistMask/issues/183)).
- 2026-08-12: The known-symbol spoof rule now judges the symbol a user actually
sees. `isSpoofedSymbol()` normalizes before the lookup — NFKC, then every
character that paints nothing removed (the format and default-ignorable