Attackathon _ Fuel Network 32302 - [Smart Contract - Low] Src ContractConfigurables hash collision
Submitted on Mon Jun 17 2024 17:31:27 GMT-0400 (Atlantic Standard Time) by @anatomist for Attackathon | Fuel Network
Report ID: #32302
Report type: Smart Contract
Report severity: Low
Target: https://github.com/FuelLabs/sway-standards/tree/348f7175df4c012b23c86cdb18aab79025ca1f18
Impacts:
Incorrect library function behaviors
Description
Brief/Intro
src12
Hash
trait implementation for ContractConfigurables
allows collision between different configurations.
Vulnerability Details
ContractConfigurables
is a vector of (offset: u64, data: Vec<u8>)
and represents the interchangeable config for contracts. The hash
method is often used to generate a single identity value that could be used to track or retrieve the configurations or contract from storage. An example of this can be found in the example contracts.
However, there are a few flaws in the hash implementation.
Due to the
u64
offset casted as araw_ptr
in theasm
block, we're doing an arbitrary memory read onoffset_ptr.copy_bytes_to(buffer, 4);
. This is clearly incorrect becauseoffset
should be a pointer into the bytecode, and not the current vm memory. Hashing based on the data in vm memory doesn't make sense here.If we fix the type casting and correctly use address storing offset instead of treating offset as a pointer, the hash still suffers from collision because only the first 4 bytes of the
u64
offset is included. Fuel data is stored in big endian, which means the offset should never execeedu32::max
, and the first 4 bytes used in hashing will always be 0.The encoding of the
Vec<u8>
data also allows for more collisions. Assuming both incorrect casting and offset length are fixed, the two configs[(0, [0]), (10, [0, 0, 0, 0, 0, 0, 0, 11, 0])]
and[(0, [0, 0, 0, 0, 0, 0, 0, 0, 10]), (11, [0])]
will still have the same hash.Without sorting the configuration entries, functionally equivalent configurations with entry orders swapped could have different hashes.
Impact Details
Depending on usage, this may lead to out-of-bound reads, hash collision for different configs, or multiple hashes for functionally identical configs. If ContractConfigurables
is used as the key in factory contracts, it might allow attacks to overwrite entries for other contracts. The exact impact depends on functionality of contracts involved.
References
https://github.com/FuelLabs/sway-standards/blob/87b39dfcd2a0fcad9d7092b0c9937ae66e3f9299/standards/src/src12.sw#L110
https://github.com/FuelLabs/sway-standards/blob/2206de75bdb5fcabfc90d33dab17878a4d7efe2f/examples/src12-contract-factory/with_configurables/src/with_configurables.sw#L99
Proof of concept
Proof of Concept
This PoC demonstrates that offset is incorrectly treated as a pointer, and could easily have hash collisions or different hashes for the same content.
Last updated