neo: `ushort` `ContractState.UpdateCounter` overflow
AN EPIC ACHIEVEMENT IS UNLOCKED:
by keeping updating the smart contract until itsUpdateCounter
jumps back to 0
although it is designed to be increased only
it is proven that UpdateCounter
is not secure any more with the hundreds of GAS cost.
i suggest to use something longer than int
to replace ushort
.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 6
- Comments: 20 (20 by maintainers)
This is transparent to the user, the address could be the same. I think that overflow
UpdateCounter
is not problematic, is just a counter, updating the contract the owner could produce more damage to the user.Yes, I meant
destroy + recreate
.The contract address is derived from NEF checksum + contract manifest name + account that deployed the contract. So it is possible to
destroy
a contract and then redeploy it and get the same contract address.Here’s a set of steps that could be used to trick people into calling a malicious contract
UpdateCounter
. These updates must also be non-maliciousYou now have a malicious contract deployed in a manner that cannot be detected.
Is there a way to ensure a destroyed contract address is not reused? I think disabling contract address reuse combined with explicitly checking for overflow when incrementing
UpdateCounter
would mitigate this issueYou can destroy and create the contract again to get UpdateCounter=0
It’s always better to test this things in private net
i think there would be no critical risk, however, it can cheat users or explorers.
i.e. onegate browser has a verified source code section and can be cheated through this way: https://testnet.explorer.onegate.space/contractinfo/0x9f89a0f5de46a085c99e6ef54a977bb37b2099b1 (however it is crashed before the cheat kkkk)
to fix it, the cheapest way can be: change the following line
https://github.com/neo-project/neo/blob/1e449185c0d05e9824c257ab4404f380106d15b2/src/neo/SmartContract/Native/ContractManagement.cs#L239
to
Being able to reset the
UpdateCounter
to zero, either by overflow or destroy + recreate, seems to defeat the purpose of havingUpdateCounter
. I get asked regularly (including in my devlog presentation today) about the security risk of supporting updatable contracts. My usual response is that the update counter can be checked to ensure the contract is the expected version. But if that value can beUpdateCounter
manipulated, an attacker could disguise their contract update and trick users into invoking a malicious contract.Maybe we should be exposing the NEF checksum or a SHA of the NEF script contents that could be used for optionally validating script contents for developers that wish to guard against this kind of attack?
cc @erikzhang @Liaojinghui