Attackathon _ Fuel Network 32973 - [Smart Contract - Medium] Impl block dependency overwriting
Submitted on Mon Jul 08 2024 17:19:46 GMT-0400 (Atlantic Standard Time) by @anatomist for Attackathon | Fuel Network
Report ID: #32973
Report type: Smart Contract
Report severity: Medium
Target: https://github.com/FuelLabs/sway/tree/v0.61.2
Impacts:
Incorrect sway compilation leading to incorrect bytecode
Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield
Description
Brief/Intro
Impl block's dependency can be overwritten by another Impl block, which can cause unexpected execution results.
Vulnerability Details
Sway allow user to declare multiple self impl block for the same type. In order to keep track of each self impl block's dependency independently, decl_name()
should assign a unique name to every self impl block to distinguish between each other, however, it uses the concatenation of all declaration name within the self impl block as its "unique name", which is not guaranteed to be unique and can collide with other self impl blocks.
The DependentSymbol
returned by decl_name()
pair with its resolved dependencies is later being insert into a single hash map. Due to above collision, a self impl block's dependency could be overwritten by another impl block, which causes dependency chain breakage.
Dependency chain breakage will usually cause a compilation error later during type checks, but when a type of the same name can be found in submodules, this will turn into a type confusion bug, which can affect execution correctness. An example is shown in the PoC section.
Impact Details
In most cases, the incorrect usage of types will be caught later during compilation. But there are scenarios where the incorrect type will be used and can cause incorrect execution results. One example is shown in the PoC section. Such incorrect type usage is dangerous, because if we encode a structure and pass it as either output message data or abi arguments, the incorrect encoding can create type confusions. In the best case scenario, those type confusions will only brick contracts. In the worst case scenario, it can lead to loss of funds bugs.
References
https://github.com/FuelLabs/sway/blob/acded67b3ec77ce1753356ad46f7ae17290f2ee0/sway-core/src/semantic_analysis/node_dependencies.rs#L945
Proof of concept
Proof of Concept## Proof of Concept
Tests are run on sway commit acded67b3ec77ce1753356ad46f7ae17290f2ee0
.
Due to dependency shadowing of impl A
, the return type of A::a
will not resolve to main::B
. Instead, it will resolve to modu::B
. meq
will return false and raise assertion because it compares two structures with different memory layouts.
We omit writing a dapp to show loss of funds caused by this bug, because the fuel team said we only need to show the incorrect compilation with our PoC in the changelog walkthrough earlier.
Last updated