HACK ANALYSIS 3 min read

Race condition in Tendermint’s StarPort


Race condition in Tendermint’s StarPort

A few months ago, during an audit of one of CredShields’ clients, we uncovered a race condition in Tendermint’s Starport that allowed any user to bypass the faucet withdrawal limits. This blog post discusses the postmortem of the race condition bug.

What is tendermint? 
Tendermint, now known as Ignite, is a core contributor to the Cosmos Network.

What is StarPort?
Starport is an open-source rapid prototyping tool that lets developers quickly build a new blockchain with just two CLI commands.

Bug Postmortem!
StarPort allows developers to configure cosmos faucets with a max credit limit through the key-value pair “coins_max” in the configuration file. 
Below is a sample configuration file with “coins_max” set to 11 tokens. This would allow any address to withdraw a maximum of 11 tokens from the faucet.

accounts:
- name: alice
coins: ["0token", "200000000stake"]
- name: bob
coins: ["500token", "100000000stake"]
validator:
name: alice
staked: "100000000stake"
client:
openapi:
path: "docs/static/openapi.yml"
vuex:
path: "vue/src/store"
faucet:
name: bob
coins: ["5token", "100000stake"]
coins_max: ["11token", "100000stake"]

But if a malicious user makes a multithread call to withdraw tokens from the faucet using 50 threads. They could withdraw more than the “coins_max” limit set in the configuration file.

The request would be as below where HOST is the faucet endpoint.

POST / HTTP/1.1
Host: 172.105.41.242:4500
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:95.0) Gecko/20100101 Firefox/95.0
Accept: application/json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://172.105.41.242:4500/
Content-Type: application/json
Origin: http://172.105.41.242:4500
Content-Length: 63
Connection: close
{
"address": "ALICE_ADDRESS"
}

We will notice although the max credit limit was set to 11 tokens, Alice managed to withdraw 30 tokens.

The root cause of the bug can be found in function “Transfer” at
https://github.com/tendermint/starport/blob/7812125/starport/pkg/cosmosfaucet/transfer.go#L50-L74
We can notice in the code that each request to the faucet causes two actions to be made; one for querying the account’s balance and the other for sending tokens. When sending concurrent requests to the faucet, in the time of querying the balance, for some requests, this check happens at the same time and ends up seeing less balance in the account because sending the tokens action has not been finalized for the previous requests.

The Fix:
We informed Tendermint’s StarPort team, and a fix was deployed. To avoid this race condition, the team added a lock to the Transfer function to put the transfer requests to the faucet into the queue, and they won’t interfere with each other.

About CredShields:
CredShields provides next-generation security services for Web3. We at CredShields are building SolidityScan.com, a cloud-based SmartContract Audit tool that allows developers to quickly scan their solidity code for security vulnerabilities and publish their report with a security score.

Timeline: 
29th Dec 2021 — Bug reported to Tendermint team 
16th Jan 2022 — Bug was fixed
19th Jan 2022 — Starport v0.19.2 was released with the fix