Skip to content

Verify SIWE signature via ECDSA recovery#170

Merged
ozpool merged 1 commit into
mainfrom
fix/siwe-signature-verification
May 29, 2026
Merged

Verify SIWE signature via ECDSA recovery#170
ozpool merged 1 commit into
mainfrom
fix/siwe-signature-verification

Conversation

@ozpool
Copy link
Copy Markdown
Owner

@ozpool ozpool commented May 29, 2026

What

Closes the auth bypass in SIWE verification. verify_siwe only length-checked the signature and trusted the Address: line in the message — so anyone could mint a JWT for any address: request a nonce for the victim, build a message quoting their address, and send any 132-char signature.

How

Recover the signer from the EIP-191 personal_sign signature (k256 ECDSA recovery + keccak256) and require it to equal the address asserted in the message before issuing a JWT. The single-use nonce check stays. The FE already signs SIWE with personal_sign, so the live flow is unaffected.

Test

  • Unit: signer round-trip recovery; malformed signatures rejected.
  • e2e: the suite now signs with a real key (asserts 200 + JWT); a forged signature for the same message is rejected with 401.
  • 34 lib + all integration tests green; fmt + clippy clean.

Notes

  • Per-order EIP-712 verification is not included: the FE's order-signing domain is still a placeholder (SETTLEMENT_PLACEHOLDER) with a 0x0000 fallback, so strict server-side order verification would reject real orders. It needs the finalized settlement-contract domain shared with the FE — tracked as a follow-up. Orders remain authenticated by the JWT, which now requires a real wallet signature to obtain.
  • External contract audit is out of scope (separate engagement, post-testnet).

siwe verify only length-checked the signature and trusted the Address
line in the message, so anyone could mint a JWT for any address by
quoting it (request a nonce for the victim, build a message, send any
132-char signature). Recover the signer from the EIP-191 personal_sign
signature with k256 + keccak256 and require it to equal the asserted
address before issuing a token; the nonce check (single-use) stays.

Adds round-trip + malformed-signature unit tests, and updates the e2e
suite to sign with a real key (and assert a forged signature is now
rejected with 401).
@ozpool ozpool merged commit dc54930 into main May 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant