# Signature malleability not protected against

Harpie used vulnerable OpenZeppelin ECDSA (<4.7.3), letting an attacker replay a malleated old changeRecipientAddress signature to redirect funds to a malicious address.

- Payout: Contest reward
- Severity: medium
- Program: Harpie
- Credited: 0xNazgul
- Disclosed: 2022-09-16
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2022-09-harpie-judging/tree/main/010-M
- Library page: https://bugbountylibrary.com/r/sherlock%3A2022-09-harpie%3AM-6
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:regression technique:source-review vuln:crypto vuln:signature-replay

**Target:** Solidity contract changeRecipientAddress signature verification
**Root cause:** Project used OpenZeppelin <4.7.3 whose ECDSA.recover accepts malleated signatures, and signatures are used for replay protection, so a malleated variant of an old signature passes the replay check.
**Steps:**
1. User calls `changeRecipientAddress()` with signature S1, then calls again with S2 after noticing a mistake.
2. Attacker takes the old S1 and computes its malleated counterpart (flip s to n-s, adjust v).
3. Attacker submits the malleated S1 to `changeRecipientAddress()` before S1 expires; ECDSA.recover returns the same signer and replay check passes.
4. Recipient is reverted to the earlier (now malicious) address, allowing attacker withdrawal.
**How found:** Compared project's OpenZeppelin version against advisory GHSA-4h98-2769-gh6h, confirming all conditions: single bytes signature arg, ECDSA.recover usage, and signatures used for replay protection.
**Exploitation:** Attacker observes an old changeRecipientAddress signature, malleates it (s -> n-s, v flipped), and resubmits before expiry to revert the recipient to a previously-set malicious address, then withdraws funds.
**Insight:** When a contract uses signatures as replay-protection nonces, check the OZ ECDSA version: pre-4.7.3 accepts malleated (s, n-s) variants, so an old signature can be replayed as a 'new' one.
