Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incoming messages from Centrifuge chain to AxelarRouter is broken #212

Closed
c4-submissions opened this issue Sep 13, 2023 · 5 comments
Closed
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-537 satisfactory satisfies C4 submission criteria; eligible for awards sufficient quality report This report is of sufficient quality

Comments

@c4-submissions
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/gateway/routers/axelar/Router.sol#L44

Vulnerability details

Bug Description

The AxelarRouter is an important smart contract that operates as follows:

  1. The Gateway smart contract encodes outgoing messages and sends them to the AxelarRouter using the AxelarRouter.send function. The AxelarRouter then forwards the message to the centrifugeGatewayPrecompileAddress on the Centrifuge chain through Axelar's General Message Passing mechanism.
  2. The AxelarRouter smart contract receives incoming messages through the AxelarRouter.execute function, which is processed by Centrifuge using Axelar's General Message Passing.

In the AxelarRouter smart contract, the AxelarRouter.execute function has a modifier that checks whether msg.sender is an AxelarGateway smart contract. However, msg.sender can never be an AxelarGateway address.

modifier onlyCentrifugeChainOrigin(
        string calldata sourceChain,
        string calldata sourceAddress
    ) {
        require(
            msg.sender == address(axelarGateway),
            "AxelarRouter/invalid-origin"
        );
        // requires
        _;
    }

Proof-of-Concept

The process unfolds as follows:
AxelarRouter --> AxelarGateway --> CentrifugeGateway --> AxelarGateway --> AxelarRouter

An example to illustrate this issue:

  1. Bob initiates any function that sends a message to the CentrifugeGateway smart contract on the Centrifuge chain through Axelar's General Message Passing, such as LiquidityPool.requestDeposit function.
  2. The CentrifugeGateway forwards the message to the AxelarGateway on the Centrifuge chain.
  3. The call is approved within the AxelarGateway on the destination chain.
  4. At this stage, the executor service relays and executes the approved call to the AxelarRouter smart contract. However, the AxelarGateway smart contract lacks the logic to invoke the AxelarRouter.execute function on AxelarRouter smart contract.

Note: Centrifuge bot pays for all executing functions automatically.

As a result, all incoming messages from the CentrifugeGateway will not be executed. You can verify this by inspecting the AxelarGateway smart contract.
You can also review AxelarScan (INTERCHAIN TRANSACTIONS) at this link. Specifically, open any transaction with the status executed and observe that there is no call from AxelarGateway to the execute function in any smart contract.

In simple terms, the approval of a contract call occurs through AxelarGateway. After that, when calling the execute function in the AxelarRouter smart contract, the validateContractCall is checked. However, msg.sender can never be an AxelarGateway address.

Impact

All incoming messages from Centrifuge chain to AxelarRouter smart contract will fail.

Tools Used

Manual

Recommended Mitigation Steps

To solve this issue, you need to remove the require:

modifier onlyCentrifugeChainOrigin(
        string calldata sourceChain,
        string calldata sourceAddress
    ) {
-        require(
-            msg.sender == address(axelarGateway),
-            "AxelarRouter/invalid-origin"
-        );
        require(
            keccak256(bytes(axelarCentrifugeChainId)) ==
                keccak256(bytes(sourceChain)),
            "AxelarRouter/invalid-source-chain"
        );
        require(
            keccak256(bytes(axelarCentrifugeChainAddress)) ==
                keccak256(bytes(sourceAddress)),
            "AxelarRouter/invalid-source-address"
        );
        _;
    }

After that, anyone will be able to call the AxelarRouter.execute function. It is protected by a validateContractCall check that only allows execution if this function returns true and the AxelarGateway marks the message as executed so that the contract call is not executed twice.

Assessed type

Invalid Validation

@c4-submissions c4-submissions added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Sep 13, 2023
c4-submissions added a commit that referenced this issue Sep 13, 2023
@c4-pre-sort
Copy link

raymondfam marked the issue as sufficient quality report

@c4-pre-sort c4-pre-sort added the sufficient quality report This report is of sufficient quality label Sep 15, 2023
@c4-pre-sort
Copy link

raymondfam marked the issue as primary issue

@c4-pre-sort
Copy link

raymondfam marked the issue as duplicate of #537

@c4-judge c4-judge added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value downgraded by judge Judge downgraded the risk level of this issue and removed 3 (High Risk) Assets can be stolen/lost/compromised directly labels Sep 26, 2023
@c4-judge
Copy link

gzeon-c4 changed the severity to 2 (Med Risk)

@c4-judge c4-judge added the satisfactory satisfies C4 submission criteria; eligible for awards label Sep 26, 2023
@c4-judge
Copy link

gzeon-c4 marked the issue as satisfactory

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-537 satisfactory satisfies C4 submission criteria; eligible for awards sufficient quality report This report is of sufficient quality
Projects
None yet
Development

No branches or pull requests

3 participants