HexBrain

Cosmos · Report #1438052

Race condition in faucet when using starport

Validstatus
criticalseverity
$5,000bounty
61upvotes
26 Jul 2022disclosed

Summary

The proper writeup of the bug can be found here at our blogpost https://blog.credshields.com/race-condition-in-tendermints-starport-7cebe176d935

The root cause of the bug was 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.

How it was found

Hi team, I and Aditya sent this bug over email on Wed, 29 Dec, 17:45 IST. Later we noticed that security reports are accepted via the HackerOne program. So, I am sending a copy of the bug report here.

Summary:

We were testing an application and we found a race condition bug in the faucet Implementation of Starport. https://github.com/tendermint/starport

Steps To Reproduce:

  1. Start a starport with the below configuration. Note the "coins_max" has been set to 11 tokens and hence a user cannot fetch more after the 11 token limits.
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"]
  1. Now call the request manually with 5 tokens per request as in our configuration after 2 requests and 10 tokens in total Alice won't be able to fetch more tokens from the faucet
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"}

Now we can confirm Alice cannot have more than 11 tokens.

  1. Now regenerate the server and instead of sending a single request send a concurrent request to fetch tokens in Alice address. We used 50 requests concurrently.

{F1563051}

  1. Now when we check Alice balance it is 30 which should have not been more than 11

{F1563052}

We believe the root cause of the issues is the go mapping which is not advised for concurrency https://github.com/tendermint/starport/blob/develop/starport/pkg/cosmosfaucet/transfer.go#L59

Supporting Material/References:

https://cwe.mitre.org/data/definitions/362.html

Impact

A malicious user can send concurrent requests to fetch more tokes from faucets than the "max-credit limit" which allows.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original