The L1BossBridge
contract uses ECDSA
signatures for authorization, but it does not appear to prevent replay attacks. An attacker could potentially replay a valid signature to authorize a transaction.
The L1BossBridge::withdrawTokensToL1
function is external and can be called by anyone. This function calls the L1BossBridge::sendToL1
function. In the sendToL1
function, a signature is used to authorize the transaction. The signature is generated off-chain and then passed into the function as the v
, r
, and s
parameters. The function uses these parameters along with the message to recover the signer's address using the ECDSA.recover
function. The problem is that the contract does not implement any mechanism to prevent the same signature from being used more than once. This means that if someone has a valid signature, he could potentially replay it to authorize multiple transactions.
If a malicious user has a valid signature, he could replay a signature for a withdrawTokensToL1
transaction. In that way a malicious user can potentially drain tokens from the vault to his own address. This is because the withdrawTokensToL1
function calls sendToL1
with a message that includes a transferFrom
call, which transfers tokens from the vault to a specified address. If a malicious user can replay this with his own address as the recipient, he could repeatedly withdraw tokens to his own address.
The following test function testUserCanWithdrawTokensWithOperatorSignatureMultipleTimes()
demonstrates how Bob (malicious user) deposits some tokens and by first call to the withdrawTokensToL1
function (Bob has a valid signature) withdraws his tokens. Alice has also deposited tokens. Then Bob calls the withdrawTokensToL1
function for the second time with a valid signature and drains the deposited amount in the vault to his own address.
The test can be added to the file L1TokenBridge.t.sol
and executed with the command: forge test --match-test testUserCanWithdrawTokensWithOperatorSignatureMultipleTimes
. Of course, in the setUp()
function of the file should be created addresses for alice and bob.
VS Code, Foundry
Implement a nonce
mechanism to prevent the replay attack. You could keep track of a nonce
for each signer. When a signer creates a signature, the current nonce
would be included in the signed data. Then the nonce
would be checked when verifying the signature, and only accept the signature if the nonce matches the stored nonce. After accepting the signature, the nonce
will be incremented, making the old nonce (and therefore the old signature) invalid. This mechanism ensures that each signature can only be used once, preventing replay attacks.
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.