The L2ContractMigrationFacet contract is vulnerable to signature replay attacks due to the absence of a nonce in its signature verification process. This allows an attacker to reuse a valid signature multiple times, potentially leading to unauthorized actions and incorrect state changes.
The verifySignature
function in the L2ContractMigrationFacet contract uses ECDSA for signature verification but lacks a mechanism to prevent signature reuse:
The function only checks the deadline but doesn't use a nonce or mark the signature as used after verification. This allows the same signature to be reused in multiple transactions as long as the deadline hasn't passed.
Duplicate redemption of deposits and internal balances, incorrect allocation of assets to the receiver address and as well as manipulation of account stalk and roots balances.
If we look at the redeemDepositsAndInternalBalances
function:
An attacker could replay a valid signature, causing duplicate calls to addMigratedDepositsToAccount
, potentially double-crediting deposits and repeated execution of setStalk
, incorrectly increasing stalk and roots balances.
Manual code review
Implement a nonce system:
Include a nonce in the signed message.
Verify and increment the nonce during signature verification.
Store used nonces to prevent reuse.
Implement a signature invalidation mechanism:
Add a function to mark signatures as used after processing.
Check if a signature has been used before processing it.
Alternatively, consider using OpenZeppelin's signature verification libraries, which often include built-in replay protection.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.