//nefariousplan

Signing Surface Poisoning

Hardware wallet / HSM / signer shows one thing, signs another. Trust boundary lives at the rendering layer.

Cryptographic signatures are supposed to be unforgeable. A properly signed transaction is proof that the signer saw the transaction and authorized it. The math works. The math has always worked.

The problem is that the signer is a person, and the person does not read bytes. The person reads a screen. A hardware wallet shows a summary. A web UI shows a preview. An admin interface shows a confirmation dialog. The signature fires on what the private key operates on, which is the bytes. What the person reviewed was the rendering. When those diverge, the rendering layer is the authorization surface, not the key.

Signing surface poisoning is the attack class where the display is the attacker's output, the bytes are the attacker's input, and the cryptography is correct about everything it is asked to be correct about.

Mechanism

Every signing workflow has the same structure. A transaction (or document, or transfer, or call) is prepared by the requesting system. The signer reviews the transaction on some surface, a hardware wallet screen, a browser tab, a mobile app, a terminal. The signer approves. The signing device performs the cryptographic operation on the bytes.

The vulnerability is the conjoining of two trust assumptions. The signer trusts that the review surface is showing them what will be signed. The cryptography trusts that whoever is signing has consented to these bytes. Both assumptions are true if the system is working correctly. Both assumptions together require that the rendering layer is authentic, complete, and attacker-free.

Break the rendering layer and the consent model collapses. The bytes that get signed are whatever the cryptographic subsystem receives. The bytes the user saw are whatever the rendering layer produced. An attacker who can inject into the rendering layer, whether through compromised JavaScript on a web UI, a modified binary on an endpoint, a rogue extension, or a display driver, gets the signer to authorize a transaction they did not actually review.

The signature is perfect. The private key is safe. The hardware wallet is uncompromised. The user consented. The transaction is valid on-chain. Every individual component of the system is behaving correctly. The outcome is the attacker's.

This pattern is not a cryptographic weakness. It is a UX weakness that cryptography cannot fix, because cryptography's job is to bind the signer to the bytes, not to guarantee the bytes match the signer's intent.

Exhibits

Bybit: $1.5B via a JavaScript Injection Nobody Was Looking For. The $1.5B exemplar. The Safe multisig UI displayed one transaction and signed a different one. The cryptographic signature was correct. The signers reviewed the displayed transaction. The display was the attacker's rendering; the signed bytes were the attacker's payload. No credential theft, no key exfiltration, no hardware wallet compromise. The trust boundary lived at the rendering layer and that is the layer that was poisoned. Cryptography delivered exactly what it promised: a binding between the private key and the bytes presented to it.

Boundaries

Not every UI-based attack. A phishing page that collects credentials is classical credential theft. Signing surface poisoning specifically requires that a LEGITIMATE private key or authorization credential be used to sign an attacker-crafted payload, with the signer believing they are signing something else. The private key stays safe; the authorization is wrongly applied.

Not every transaction replay. Replay attacks reuse a legitimately signed transaction. Signing surface poisoning produces a freshly signed transaction from a legitimate signer, on bytes the signer did not review. The distinction matters for incident response: in replay you find and invalidate the replayed signature; in signing surface poisoning the signature is valid and cannot be repudiated.

Not every hardware wallet bypass. If the attacker exfiltrates the private key, that is a key theft, not surface poisoning. The pattern describes the case where the key never leaves its secure enclave and the signer's finger still pressed the approve button. The enclave was honest. The display was not.

Defender playbook

For every signing workflow you rely on, identify the rendering surface the user reviews and the cryptographic surface that produces the signature. If those live in different processes, different domains, different devices, or different teams, the gap between them is your exposure. The larger the stack between "what the user saw" and "what got signed," the more attack surface the rendering side accumulates.

On hardware wallets specifically, the device must display every material field of the transaction on its own trusted screen. If the device blind-signs, or shows only a hash, the rendering is effectively the host computer's, and the hardware wallet is reduced to an expensive key-storage device. Reject workflows that rely on host-rendered summaries for anything of value.

Audit the rendering stack the same way you audit the cryptographic stack. Browser extensions, overlays, injected content, patched clients. The signer's confidence comes from what their eyes see. That pipeline needs the same integrity expectations as the key pipeline, and usually has far less.

Separate high-value signing from routine signing. Treating every signature as equivalent collapses into the lowest-trust rendering workflow. Multisig schemes for high-value operations with diverse rendering surfaces (different devices, different UI stacks, different organizations) defeat single-point signing surface poisoning because the attack would need to poison every surface simultaneously.

Log what gets signed at the byte level, server-side, and compare against what the user was shown. Post-hoc audit is not prevention, but it closes the "did the signer actually see this" loop for later incidents. Many signing systems log only that a signature occurred, not the full transaction and not the UI state.

Kinship

Trust Inversion. The rendering layer is an authorizer, and when it is compromised the authorizer is inverted. Signing surface poisoning is a specific locus of trust inversion: the authorizer is the display pipeline, not a key or account.

Content Is Command. The rendered preview is content. When the preview is generated by attacker-influenced code, the content is producing a command (the signature) via the signer's eyes and hands. Signing surface poisoning is a high-stakes instance of content-is-command, with the interpreter being the human reviewer.

Security Tool As Primitive. Hardware signing devices are security tools in the trust sense: they exist to protect key material. When the rendering layer is the attack surface, the tool's defense (key security) is intact while the tool's value proposition (intentful signing) is compromised. The tool remains the authorizer. The authorization is meaningless.

The cryptography signed what it was given. What the signer saw was not what it was given.