Attackathon _ Fuel Network 33488 - [Smart Contract - Medium] Insecure implementation of StorageMap c

Submitted on Sun Jul 21 2024 20:51:55 GMT-0400 (Atlantic Standard Time) by @jecikpo for Attackathon | Fuel Network

Report ID: #33488

Report type: Smart Contract

Report severity: Medium

Target: https://github.com/FuelLabs/sway/tree/v0.61.2

Impacts:

  • Direct theft of any user NFTs, whether at-rest or in-motion, other than unclaimed royalties

  • Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield

  • Security Best Practices

  • Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)

Description

Brief/Intro

Currently StorageMap implementation could lead to unintended storage slot overwrites if misused by the developer. StorageMap uses hashing mechanism (through the usage of field_id provided by the developer) to create unique storage slot values by hashing the key through the field_id. Nothing however prevents from reusing the field_id in a different StorageMap instance and hence having the two StorageMap instances collide.

Vulnerability Details

Sway offer a StorageMap facility for secure key-value data writing into contract's storage. It uses the field_id to hash the key and create a unique storage slot value.

This works correctly when the developer ensures the uniqueness of the field_id. In the future however when the ecosystem grows and dapps are composed of multiple different libraries written by different parties, this will become harder to ensure.

Impact Details

While this is not strictly a bug in the code, it is a faulty library design which might have consequences for future projects. In the event of StorageMap collision the impact can be severe as the storage overwritten could result in users assets stolen, as the StorageMap shall be used to store the state of user's interaction with the dapp.

An example would be a vault which uses StorageMap to record users's deposits. Another overlapping StorageMap could then be leveraged to create mallicious entries which would then be read by the first StorageMap and hence fake deposits could be created.

The security of StorageMap relies heavily on correctness of the implementation and as Fuel demonstrated strong intent of enforcing correctness of implementation (e.g. through the CEI verification during compile time), I think it is correct to report this under High severity.

Solution Proposal

I created a draft of SecureStorageMap implementation which is based on how Solidity creates unique slots for multiple mappings. It's description along with code can be found here for reference:

https://gist.github.com/jecikpo/f4508ab48ef91ca42866fcc1645998a4

References

The current implementation: https://github.com/FuelLabs/sway/blob/4adae25aa7e5b954c4c87bd5c683a79c3373f540/sway-lib-std/src/storage/storage_map.sw#L54

Proof of concept

Proof of Concept

PoC along with description can be found here: https://gist.github.com/jecikpo/5fc57811142c96f85e83037386bfade5

Last updated