Broken NonceVoter
Allows Observer to Halt the Chain
#547
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
H-01
primary issue
Highest quality submission among a set of duplicates
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2023-11-zetachain/blob/b237708ed5e86f12c4bddabddfd42f001e81941a/repos/node/x/crosschain/keeper/keeper_chain_nonces.go#L106-L147
Vulnerability details
Impact
As it is,
NonceVoter
does not count votes or perform any similar operations. A single observer can use it to change chain nonces. Although there is a comment pointing this function is deprecated, it critically influences the system with its broken implementation. Arbitrarily changing nonces for the connected chains can be used to completely break the functioning of the chain and cause loss of funds.Proof of Concept
This function is restricted to validator observers (
k.zetaObserverKeeper.IsAuthorized(ctx, msg.Creator, chain)
):After this check, the entire voting logic is essentially ignored, with a relevant part only drafted and commented, and the chain nonce is simply set:
This can be easily tested inside one of the hosts in the smoke-tests:
After the above commands, you can also use the command
zetacored q crosschain list-chain-nonces
insidezetacored1
to check the1337
nonce has been set.p.NonceHigh != int64(nonce.Nonce)
One simple way to halt critical operations of the chain and cause funds to be stuck is to make the function
UpdateNonce
incctx_utils.go
fail. Luckily, there is a check that causes this function to fail and return an error, and all we need to do is to change the chain nonce:All a faulty or compromised observer needs to do is to use
NonceVoter
to desyncrhonise the nonces for each chain, and this error will be consistently returned byUpdateNonce
for all chains.These are critical functions that depend on
UpdateNonce
:MigrateTSSFundsForChain
ProcessCCTX
VoteOnObservedInboundTx
VoteOnObservedOutboundTx
*
WhitelistERC20
Essentially, transactions will be halted and the funds stuck.
Tools Used
Manual: code editor, docker.
Recommended Mitigation Steps
Implement the correct voting logic or remove this message server's function from the code. In the codebase, it seems there is already another design choice for setting chain nonces that does not depend on this function, so the best mitigation is probably to remove this function altogether.
Assessed type
Access Control
The text was updated successfully, but these errors were encountered: