The typed data screen lists message keys that are not signed #539

Open
opened 2026-10-14 06:16:58 +02:00 by clawbot · 2 comments
Collaborator

Where. formatTypedDataHtml() in src/popup/views/approval.js:662-668 lists every key of the typed data's message, and shows a nested value as JSON with every key in it. ethers signs only the fields the type declares and drops the rest (comment at approval.js:476-479).

What happens. A site can put keys beside the declared fields, and the Message section shows them as if they were signed. Example: a Permit whose type names its spender operator, set to the attacker, plus an undeclared spender set to a harmless-looking address and a note: "This signature only signs you in". All three appear as message lines; only operator is signed. For typed data that raises no token permission warning, such as a marketplace order, nothing on the screen contradicts the added lines.

The test "an added key is not named as the spender" in tests/typedDataPermit.test.js checks only the warning box, so it passes while the decoy is listed under Message.

Should. README SignApproval shows the typed data's fields so the user can see what is signed. A line that is not signed must not be among them.

Severity: major

Definition of done

  • The Message section shows only the fields the signed type declares, at every level of nesting.
  • A key the type does not declare is never shown as a message line: such typed data is refused, or those keys are listed under their own heading saying they are not signed. README SignApproval states which.
  • That test also checks the Message section, and a test covers an undeclared key inside a nested struct.

Model: opus-5-5

**Where.** `formatTypedDataHtml()` in `src/popup/views/approval.js:662-668` lists every key of the typed data's `message`, and shows a nested value as JSON with every key in it. ethers signs only the fields the type declares and drops the rest (comment at `approval.js:476-479`). **What happens.** A site can put keys beside the declared fields, and the Message section shows them as if they were signed. Example: a `Permit` whose type names its spender `operator`, set to the attacker, plus an undeclared `spender` set to a harmless-looking address and a `note: "This signature only signs you in"`. All three appear as message lines; only `operator` is signed. For typed data that raises no token permission warning, such as a marketplace order, nothing on the screen contradicts the added lines. The test "an added key is not named as the spender" in `tests/typedDataPermit.test.js` checks only the warning box, so it passes while the decoy is listed under Message. **Should.** README SignApproval shows the typed data's fields so the user can see what is signed. A line that is not signed must not be among them. Severity: major ## Definition of done - [ ] The Message section shows only the fields the signed type declares, at every level of nesting. - [ ] A key the type does not declare is never shown as a message line: such typed data is refused, or those keys are listed under their own heading saying they are not signed. README SignApproval states which. - [ ] That test also checks the Message section, and a test covers an undeclared key inside a nested struct. Model: opus-5-5
clawbot self-assigned this 2026-10-14 06:16:58 +02:00
Author
Collaborator

Plan: the Message section lists only the fields the signed type declares, at every level of nesting, in the type's order. Keys the type does not declare are not refused (sites do send extra keys), but they are listed after the message under their own heading, "Not part of the signature", so nothing unsigned reads as signed. README.md SignApproval says so. Tests: the existing "an added key is not named as the spender" test also checks the Message section, and a new one covers an undeclared key inside a nested struct.

Model: opus-5-5

Plan: the Message section lists only the fields the signed type declares, at every level of nesting, in the type's order. Keys the type does not declare are not refused (sites do send extra keys), but they are listed after the message under their own heading, "Not part of the signature", so nothing unsigned reads as signed. `README.md` SignApproval says so. Tests: the existing "an added key is not named as the spender" test also checks the Message section, and a new one covers an undeclared key inside a nested struct. Model: opus-5-5
Author
Collaborator

Built as planned above, in #551. An extra key is listed by its place in the message, written as a path such as details[1].note.

Model: opus-5-5

Built as planned above, in https://git.eeqj.de/sneak/AutistMask/pulls/551. An extra key is listed by its place in the message, written as a path such as `details[1].note`. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#539