Boost _ Folks Finance 33534 - [Smart Contract - Medium] denial of service vulnerability and possible griefing in cross-chain account creation
Last updated
Was this helpful?
Last updated
Was this helpful?
Submitted on Mon Jul 22 2024 16:38:28 GMT-0400 (Atlantic Standard Time) by @A2Security for
Report ID: #33534
Report type: Smart Contract
Report severity: Medium
Target: https://testnet.snowtrace.io/address/0x3324B5BF2b5C85999C6DAf2f77b5a29aB74197cc?utm_source=immunefi
Impacts:
Griefing (e.g. no profit motive for an attacker, but damage to the users or the protocol)
The implementation of the createAccount()
function in the spoke and hub contract allows a potential Denial of Service (DoS) attack, where an attacker can exploit the account creation process across different chains. When a user attempts to create an account from a spoke chain, an attacker can listen for this transaction on the source chain and preemptively call the createAccount()
function on the hub chain using the same account ID. This results in the victim's transaction reverting, as the attacker effectively blocks the user's ability to create an account with the intended ID.
This vulnerability can have catastrophic consequences, allowing attackers to prevent any or all users from creating cross-chain accounts. Users who send a cross-chain message will not only be unable to create the desired account but also risk losing the funds already paid to cover the cross-chain delivery and execution of the message. This leads to a significant loss of trust in the protocol, as users may find themselves unable to access the services they expected, further impacting user retention and engagement.
Here’s how the createAccount()
function is invoked on the spoke contract:
In this code snippet, the createAccount()
function accepts transaction parameters and unique identifiers for the account being created. The critical part is the call to _doOperation
, which is responsible for creating a message that will be forwarded through the bridging protocol (such as Wormhole or CCIP) to the hub chain. As we can see the accountId is a free parameter that the user can set it to anything want to.
The message will be then recieved in the Hub contract and the AccountManager
where it will be processed by the createAccount()
function, and if this accountId
is already reserved the transaction will revert.
Manual review
1Implement a mechanism to hash the user address (msg.sender
in the source chain) along with the chain ID when generating account IDs. This will ensure that account IDs are unique across users and chains, preventing the possibility of attackers blocking legitimate account creation attempts.
The vulnerability can be demonstrated as follows:
A user sends a transaction to create an account from a spoke chain (e.g., Spoke A).
An attacker observes this transaction on Spoke A and calls the createAccount()
function on the hub chain (e.g., Hub B) using the same account ID.
When the user's transaction is forwarded to the hub chain, it reverts because the account ID has already been registered by the attacker.