Axelar is a cross-chain bridging protocol. To come to an agreement on whether a cross-chain vote has happened or not, 60% of the stake on Axelar has to approve it. The voting is performed on the Axelar blockchain, which is a Cosmos SDK chain. To off-chain listener is called vald.
There are uptime requirements for all of the voters, called chain maintainers, of a particular chain. Validators who miss votes will be deregistered and lose rewards.
Once the ContractCall on an Axelar gateway contract is made, the vald program will see this and vote on the Cosmos Axelar chain. To do this, they call ConfirmGatewayTxs.
While reviewing the configuration settings of the Axelar chain validators, they noticed the max_body_bytes setting. This is the maximum amount of bytes that can be in a request - 1MB. If this limit is exceeded, then the Axelar node will drop the request. These settings are seldomly changed and is the default value in the official setup instructions. By forcing the ConfirmGatewayTxs to be larger than 1MB, with excessive amounts of logs, the voting transactions from vald would be rejected!
By itself, this isn't a huge deal. However, considering the voting penalties is where this becomes interesting. Remember, if a certain amount of votes are missed, then the chain maintainers are deregistered. The voting has no minimum quorum check. If there's a poll to vote on, even if nobody can vote or does vote, the chain maintainers will get slashed for this.
The author of the cost does some cost analysis. To take down all major chains, it would cost 5K. In the future, it would cost another $11 per chain to do this again. Here's the flow of the attack:
- Create 2 malicious transactions that make 2000
ContractCall logs on the Axelar Gateway.
- Call
ConfirmGatewayTxs on Axelar with the txids from the events listed. At this point, vald detects the polls and tries to vote but fails because of the size of the HTTP request.
- Do step 2 over and over again until the chain maintainers are deregistered.
The impact of this is pretty severe - it stops Axelar in its tracks on all chains. Initially, Axelar rated this as medium and asked to pay 5K with this being considered a "liveness vs. security" issue, increasing this to 20K but this was still rejected. After multiple follow ups from Immunefi, this was upgraded to a critical at 50K. You gotta love Immunefi and their help towards hackers!
This vulnerability is a great win for public disclosure. The bug had not been fixed when this was published. However, within a few days of publishing the post, the issue was fixed by disabling auto-deregistration altogether. Without the public disclosure, this vulnerability may not have been fixed.
To me, the real vulnerability was the missing minimum vote check before slashing. It's weird that Axelar fixed this by removing the deregistration. I personally love this post of taking a "small thing" to abuse a fundamental design issue.