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.