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

AxelarRouter.execute will always revert causing all messages to not be processed #442

Closed
c4-submissions opened this issue Sep 14, 2023 · 7 comments
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 low quality report This report is of especially low quality satisfactory satisfies C4 submission criteria; eligible for awards

Comments

@c4-submissions
Copy link
Contributor

Lines of code

centrifuge/blob/main/src/gateway/routers/axelar/Router.sol#L44

Vulnerability details

Impact

AxelarRouter.execute has the onlyCentrifugeChainOrigin modifier, which assumes msg.sender is axelarGateway. This is wrong because axelarGateway never does this. msg.sender is the relayer from Axelar. Therefore, this function will revert due to the check in onlyCentrifugeChainOrigin, which has two impacts:

  1. The gas paid for all messages will be drained. This will lead to funds loss from protocol.
  2. All messages cannot be processed, and the core functions of the protocol are significantly broken. Assets deposited by users can never be withdrawn.

Proof of Concept

According to axelar's docs, we can understand that cross-chain messages need to go through 3 phrases (6 steps). Let's see how messages are processed:

At the source chain

  1. User (dApp) calls a callContract (or callContractWithToken) function on the Axelar Gateway contract to initiate a call. Once the call is initiated, the user can see its status at [https://axelarscan.io/gmp/txHash] or programmatically track it via the AxelarJS SDK.
  2. User prepays the relayer gas fee on the source chain to Axelar’s Gas Services contract.
  3. The call enters the Axelar Gateway from the source chain.

At the Axelar network

  1. Axelar network confirms the call and converts the paid gas from the source chain’s native token into the destination chain’s native token.

At the destination chain

  1. The call is approved and emerges from the Axelar Gateway on the destination chain.
  2. The executor service relays and executes the approved call to the application’s Axelar Executable interface.

In Axelar Gateway, each message will calculated as a hash value via keccak256, which represents the stored slot. If the value of this slot is true, it means that the message can be executed. The 5th step is to set the slot corresponding to the message to true. Next, the executor service from Axelar (commonly known as relayer) calls the execute method of the target contract of the message. In this case, it's Router.execute.

File: src\gateway\routers\axelar\Router.sol
73:     function execute(
74:         bytes32 commandId,
75:         string calldata sourceChain,
76:         string calldata sourceAddress,
77:         bytes calldata payload
78:->   ) public onlyCentrifugeChainOrigin(sourceChain, sourceAddress) {
79:         bytes32 payloadHash = keccak256(payload);
80:         require(
81:             axelarGateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash),
82:             "Router/not-approved-by-gateway"
83:         );
84: 
85:         gateway.handle(payload);
86:     }

43:     modifier onlyCentrifugeChainOrigin(string calldata sourceChain, string calldata sourceAddress) {
44:->       require(msg.sender == address(axelarGateway), "AxelarRouter/invalid-origin");
......
54:     }

So, at L44, tx will revert since msg.sender is not axelarGateway.

L80-83, This implementation method has guaranteed the validity of the message. axelarGateway.validateContractCall(commandId, sourceChain, sourceAddress, payloadHash) will internally check whether the slot corresponding to the message is true. If it is true, set it to false and return the original bool.

Tools Used

Manual Review

Recommended Mitigation Steps

Remove the check at L44.

Assessed type

DoS

@c4-submissions c4-submissions added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Sep 14, 2023
c4-submissions added a commit that referenced this issue Sep 14, 2023
@c4-pre-sort c4-pre-sort added the low quality report This report is of especially low quality label Sep 15, 2023
@c4-pre-sort
Copy link

raymondfam marked the issue as low quality report

@c4-pre-sort
Copy link

raymondfam marked the issue as duplicate of #26

@c4-judge
Copy link

gzeon-c4 marked the issue as unsatisfactory:
Invalid

@c4-judge c4-judge added unsatisfactory does not satisfy C4 submission criteria; not eligible for awards and removed duplicate-26 labels Sep 26, 2023
@c4-judge
Copy link

gzeon-c4 marked the issue as not a duplicate

@c4-judge
Copy link

gzeon-c4 marked the issue as duplicate of #537

@c4-judge
Copy link

gzeon-c4 marked the issue as satisfactory

@c4-judge c4-judge added satisfactory satisfies C4 submission criteria; eligible for awards 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 unsatisfactory does not satisfy C4 submission criteria; not eligible for awards 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)

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 low quality report This report is of especially low quality satisfactory satisfies C4 submission criteria; eligible for awards
Projects
None yet
Development

No branches or pull requests

3 participants