Beginner FriendlyFoundryBridge
100 EXP
View results
Submission Details
Severity: high
Valid

Signature replay attack on `L1BossBridge`

Summary

The L1BossBridge::sendToL1() method is vulnerable to signature replay attack, allowing the attacker to steal the funds from the bridge.

Vulnerability Details

The L1BossBridfe::sendToL1() method is responsible for withdrawing tokens from L2 to L1.

function sendToL1(uint8 v, bytes32 r, bytes32 s, bytes memory message) public nonReentrant whenNotPaused {
address signer = ECDSA.recover(MessageHashUtils.toEthSignedMessageHash(keccak256(message)), v, r, s);
if (!signers[signer]) {
revert L1BossBridge__Unauthorized();
}
(address target, uint256 value, bytes memory data) = abi.decode(message, (address, uint256, bytes));
(bool success,) = target.call{ value: value }(data);
if (!success) {
revert L1BossBridge__CallFailed();
}
}
}

The method accepts the message (the address of the token, value to withdraw and the recipient) and a signature. If the signature is valid and the signer is a valid signer, the transfer gets executed.

The issue is the method does not have any checks against signature replay attack. That means the attacker can reuse the signature multiple times to execute the transfer repeatedly, therefore stealing the money. The attacker can also reuse the signature on different chains where L1BossBridge contract will be deployed.

Impact

Tokens can be stolen from the bridge

Tools Used

Manual review, Patrick's audit course curriculum

Recommendations

Implement EIP-712 protections against cross-chain signature replay and keep track of the already used signatures to prevent the replay on the same chain.

Updates

Lead Judging Commences

0xnevi Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

withdrawTokensToL1()/sendToL1(): signature replay

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.