harden: show a personal message's hex and mark control characters in its text (closes #403)
The signature screen showed only the text a personal message decodes to, with bidirectional and zero-width characters acting on it, so a site could make the message read differently from the bytes that are signed, and a message that was not hex was decoded into NUL characters. The screen now shows the hex as "Raw data" alongside the decoded text, and each control or format character in the text as a U+XXXX mark. Signing takes the bytes from the hex, so a message that is not hex cannot be signed: it is shown as plain text, with the error line saying so and "Sign" disabled. Model: opus-5-5
This commit is contained in:
@@ -1920,8 +1920,13 @@ view would leave a wallet one click from deletion.
|
||||
- Danger warning box (shown for `eth_sign`, which signs a raw hash)
|
||||
- Type: "Personal message" or "Typed data (EIP-712)"
|
||||
- From: color dot + full address + etherscan link
|
||||
- Message: decoded UTF-8 text (personal_sign) or formatted domain/type/
|
||||
message fields (EIP-712 typed data). The primary type shown is the one
|
||||
- Message: for `personal_sign` and `eth_sign`, the text the message's bytes
|
||||
decode to as UTF-8, with each control or format character (zero-width and
|
||||
bidirectional characters among them) shown as a bordered `U+XXXX` mark
|
||||
instead of acting on the text, so it reads in the order of the bytes that
|
||||
are signed; a line feed is shown as a line break. Bytes that are not UTF-8
|
||||
are shown as "This message is not text." For typed data, formatted
|
||||
domain/type/message fields (EIP-712). The primary type shown is the one
|
||||
ethers signs, derived from the typed data's `types`, not the type the site
|
||||
states.
|
||||
- Token permission warning, at the top of the message (typed data whose
|
||||
@@ -1935,12 +1940,20 @@ view would leave a wallet one click from deletion.
|
||||
domain's `verifyingContract`; any those fields do not give is shown as
|
||||
`Unknown`, and the domain, type and message lines still follow. Only typed
|
||||
data that cannot be read at all is shown as raw text.
|
||||
- Raw data (`personal_sign` and `eth_sign`): the message's hex exactly as
|
||||
the site sent it. The bytes it encodes are what is signed, as an EIP-191
|
||||
personal message.
|
||||
- Password input and an error line
|
||||
- "Sign" / "Reject" buttons
|
||||
- **Transitions**:
|
||||
- Typed data that states no primary type, or one other than the type it
|
||||
would be signed as, or that cannot be read → shown with the error line
|
||||
saying so and "Sign" disabled; only "Reject" remains
|
||||
- A `personal_sign` or `eth_sign` message that is not hex (`0x` and an even
|
||||
number of hex digits) → shown as plain text, with the error line "This
|
||||
message is plain text, not hex, so it cannot be signed." and "Sign"
|
||||
disabled; signing takes the bytes from the hex, so such a message has none
|
||||
to sign
|
||||
- "Sign" (correct password) → signs locally → closes popup (returns
|
||||
signature)
|
||||
- "Sign" (wrong password, or a signing failure) → error line, no screen
|
||||
|
||||
Reference in New Issue
Block a user