harden: personal_sign display decodes only hex and renders control and bidirectional characters verbatim, without the raw bytes #403

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

Severity: hardening.

Where. src/popup/views/approval.js:369-381 (decodeHexMessage) and
441-447 (the personal_sign message display).

What is wrong. decodeHexMessage slices two characters off the string and
parses the rest as hex byte pairs, so a message that is not 0x-prefixed hex
decodes to NUL/garbage; and a valid hex message that decodes to text containing
bidirectional overrides or zero-width characters is shown verbatim, so what the
user reads can differ from the byte order that signer.signMessage signs. The
raw hex is not shown alongside the decoded text.

Why it matters. A page can make the displayed message read differently from
what is signed.

Reproduction. A personal_sign request whose hex decodes to text containing
U+202E (right-to-left override) around a substituted clause renders reordered; a
non-hex message renders as invisible NUL characters.

Acceptable. Show the raw hex bytes alongside any decoded text; validate that
the input is hex before decoding; strip or visibly mark control and
bidirectional characters in the decoded view.

Definition of done.

  • The personal_sign screen shows the raw hex bytes as well as any decoded
    text.
  • Control and bidirectional characters are escaped or visibly marked in the
    decoded view.
  • A non-hex message is shown as such rather than as NUL characters.
  • A test asserts a bidi-override message is rendered without reordering the
    visible text.

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

Severity: hardening. **Where.** `src/popup/views/approval.js:369-381` (`decodeHexMessage`) and `441-447` (the personal_sign message display). **What is wrong.** `decodeHexMessage` slices two characters off the string and parses the rest as hex byte pairs, so a message that is not `0x`-prefixed hex decodes to NUL/garbage; and a valid hex message that decodes to text containing bidirectional overrides or zero-width characters is shown verbatim, so what the user reads can differ from the byte order that `signer.signMessage` signs. The raw hex is not shown alongside the decoded text. **Why it matters.** A page can make the displayed message read differently from what is signed. **Reproduction.** A personal_sign request whose hex decodes to text containing U+202E (right-to-left override) around a substituted clause renders reordered; a non-hex message renders as invisible NUL characters. **Acceptable.** Show the raw hex bytes alongside any decoded text; validate that the input is hex before decoding; strip or visibly mark control and bidirectional characters in the decoded view. **Definition of done.** - [ ] The personal_sign screen shows the raw hex bytes as well as any decoded text. - [ ] Control and bidirectional characters are escaped or visibly marked in the decoded view. - [ ] A non-hex message is shown as such rather than as NUL characters. - [ ] A test asserts a bidi-override message is rendered without reordering the visible text. Model: fable-5-1 (review); opus-4-8 (filing)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/AutistMask#403