📲Arbitrary Contract Calls from Unsanitized Paths

Vulnerability Overview

In decentralized systems that allow swapping between tokens, it is common for protocols to provide users with the flexibility to define their swap paths. This flexibility becomes a critical vulnerability when the paths are not validated properly, allowing malicious actors to craft swap paths that include arbitrary contract calls. Such an exploit enables attackers to take control of protocol logic and execute unauthorized transactions, potentially resulting in financial loss or protocol disruption.

A prime example of this vulnerability is seen when a function allows the user to provide a custom swapPath for a token swap. If the path is not fully validated, malicious tokens or contracts can be included in the intermediate steps of the swap, which can then trigger unwanted side effects such as token theft, unauthorized contract calls, or system exploitation.

How the Exploit Occurs

Let’s explore a specific scenario where this vulnerability arises. In this example, a contract allows users to provide a swapPath for swapping tokens using Uniswap V3. However, the protocol does not fully validate the tokens or contracts included in the swap path, leading to an arbitrary contract call vulnerability.

function _swap(bytes memory swapPath, uint256 amount) internal {
    // User provides swapPath, which is used directly without validation
    swapRouter.exactInput(
        ISwapRouter.ExactInputParams({
            path: swapPath,
            recipient: address(this),
            amountIn: amount,
            amountOutMinimum: 0
        })
    );
}

In the above example:

  • User-Controlled Path: The swapPath is controlled by the user and is used in the token swap without any checks on its validity.

  • Unvalidated Path: There is no validation to ensure that the intermediate tokens in the swap path are legitimate or that the contracts being called are safe.

This opens the door for an attacker to craft a malicious swap path as follows:

  1. Create a malicious token or contract.

  2. Deploy it to the network and pair it with legitimate tokens in a Uniswap V3 pool.

  3. Provide the malicious contract as an intermediate step in the swap path.

Once the swap is executed, the malicious contract’s transfer or call functions are triggered, allowing the attacker to perform unauthorized actions such as stealing tokens, modifying balances, or making arbitrary calls to external contracts.

Real-World Example: Li.Fi Attack

In the Li.Fi exploit in July 2024, a similar vulnerability was exploited when an attacker was able to pass unsanitized data into a function, allowing arbitrary calls to be executed. This vulnerability was a result of improper validation of user-provided input, specifically the _swapData field, which allowed the attacker to call any function, leading to the loss of millions of dollars. The Li.Fi exploit demonstrates the devastating consequences of not validating user-provided input, especially in contexts where low-level calls are made.

Impact

The impact of such vulnerabilities can be significant:

  1. Token Theft: The attacker can manipulate the swap path to steal tokens or perform unauthorized transfers.

  2. Arbitrary Contract Execution: Attackers can inject arbitrary function calls into the contract execution flow, potentially draining funds or disrupting the protocol’s operations.

  3. Financial Loss: As seen in the Li.Fi attack, improper validation of paths can result in millions of dollars in losses.

  4. Protocol Reputation Damage: These vulnerabilities can severely damage the reputation of a protocol, resulting in lost user trust and confidence.

Last updated