Closed code423n4 closed 2 years ago
While this might seem as an issue if you look at the contract as a standalone, it is not when you look at it as part of the solution, working with the gravity module. The batch nonce is automatically incremented in the cosmos Gravity module, so unless we have malicious validators with higher than the threshold power, this would not happen.
The code for the batch construction can be found here: https://github.com/code-423n4/2022-05-cudos/blob/main/module/x/gravity/keeper/batch.go#L53
Lines of code
https://github.com/code-423n4/2022-05-cudos/blob/main/solidity/contracts/Gravity.sol#L290 https://github.com/code-423n4/2022-05-cudos/blob/main/solidity/contracts/Gravity.sol#L385 https://github.com/code-423n4/2022-05-cudos/blob/main/solidity/contracts/Gravity.sol#L495
Vulnerability details
Impact
The purpose of the nonces in the Gravity bridge are to ensure that old confirmed transactions can't be resubmitted and mutate state again. To ensure this doesn't occur the contract checks to verify that the new nonce is greater than the old nonce. However, it doesn't set an upper bound for the nonce. Thus, it is theoretically possible for the nonces to be set to
MAX_UINT
, at which point all calls to the relevant contract methods will fail. This situation would require the validators to sign a transaction with the offending nonce, but if this did occur the bridge would be unable to facilitate further transfers.Proof of Concept
The contract uses the following states that keep track of nonces that are passed in as arguments:
For the methods
submitLogicCall
,submitBatch
andupdateValset
, they all have a similar check that validates whether the new nonce passed in as an argument is greater than the previously stored nonce, for example:The state is then updated to the new nonce value:
If the new nonce were
MAX_UINT
then the call would pass, but the following call would always fail since no number can be greater thanMAX_UINT
.Tools Used
VSCode
Recommended Mitigation Steps
Depending on how aggressive you want the check on the new nonces to be, you can either:
and then update the relevant require statements in the previously mentioned methods. e.g.