Attackathon _ Fuel Network 33351 - [Smart Contract - Critical] ABI supertraits methods are available
Last updated
Was this helpful?
Last updated
Was this helpful?
Submitted on Thu Jul 18 2024 13:00:58 GMT-0400 (Atlantic Standard Time) by @cyberthirst for
Report ID: #33351
Report type: Smart Contract
Report severity: Critical
Target: https://github.com/FuelLabs/sway/tree/v0.61.2
Impacts:
Compiler bug
ABI supertraits are, as the docs say, intended to make contract implementations compositional. As such they allow to define methods that can be inherited by the contract implementing the trait. However, what is essential is that these methods shouldn't be available externally as contract methods. However, this is not the case, and the methods are available externally.
The docs say:
Also, in the compiler, we can read :
Additionally, suppose that the method renounce_ownership
comes from a supertrait and we try to call it from a test like this:
Then we get the following compile error
If we inspect the build artifacts, namely the contract-abi.json file, we'll see that the file is generated correctly, i.e. the supertrait methods are not in there.
However, if we inspect the IR of the generated contracts, we can see that the super traits methods are available in function dispatch. This is also proved and shown in the PoC.
Putting it all together, we established that the supertrait methods shouldn't be available as contract methods. However, as we will show, they actually are.
The function is called to collect the contract function. As we can see, it matches against ImplTrait
, and there isn't any further validation.
This bug makes supertrait methods externally available, i.e. methods which should be private are publicly available and can be immediately called by an attacker.
This is extremely critical because private methods usually don't employ access controls as they shouldn't be available to external users.
As such, one of the most essential forms of access control is broken.
Because this behavior will almost never be tested by the users of Sway (because this behavior is assumed to be guaranteed by the compiler), it has very low likelihood to be discovered during testing.
In the PoC, we should that function renounce_ownership
, which should be private, is actually public. As such, it can be called by an attacker - which we demonstrate. The end result is that the owner loses the ownership of his contract.
This whole sequence is demonstrated via the following asserts:
To run the PoC, just unzip and run forc test
.
Also, if we inspect the supertraits-poc-abi.json
file and check the contract functions, we get:
as can be seen, the supertrait methods aren't available.
Link to Google Drive with the PoC: https://drive.google.com/file/d/1jxEiA55O9XkWiIbYqf0-j9zNy_pzmiOw/view?usp=sharing
Or in :
Also, the compiler test tests that the methods aren't available. The test correctly fails, but we think it's exactly because the abi file is generated correctly (but the actual code isn't).
The cause of the issue should be the following function :
After the functions are collected, they are passed to generate_contract_entry
which is responsible for the dispatch. And therefore the function are made externally available.