cardano-community / guild-operators

Artifacts and scripts created by Guild operators
https://cardano-community.github.io/guild-operators
MIT License
354 stars 177 forks source link

Koios must offer time based ordering to results of account payment addresses list #1537

Closed benapetr closed 2 years ago

benapetr commented 2 years ago

Right now, Koios doesn't seem to sort the results in any way, this may result in major security vulnerability for all tools that are using this feature.

To explain why this is needed - cardano allows creation of payment address with spoofed staking key, that means you can create address that belongs to some wallet, but contains staking key of another wallet. In order to reliably translate staking address to payment address, you should always work with a first payment address that contains given staking key that appeared on the blockchain. That way you can be confident this is most likely a payment address that really belongs to the wallet of the staking key.

To explain why this matter:

Now imagine following scenario with victim, tool and hacker - victim has wallet A with 3 payment addresses that were ever used in blockchain. Koios returns 3 addresses on the API call. Now this wallet is enrolled in some DripDropz / Tosi / Whatever tool that uses Koios, where they are eligible to withdraw some valuable reward. Normally when someone wants to withdraw reward from the tool, they send a deposit from their wallet and the tool sends them the reward they wanted to withdraw back. However since the staking key can be spoofed, the tool must not automatically use the same address that the deposit came from. Instead it will take the staking key and ask Koios what is the payment address for it, however right now the results from Koios have random order. Hacker that wants to steal this reward has following option - they create 100 spoofed payment addresses and make TX on each of them. Now Koios call for payment addresses will return 103 addresses, only 3 of them belonging to victim, 100 of them belonging to hacker. When the victim tries to withdraw their reward, the first returned payment address is most likely going to belong to hacker and funds will get stolen.

How to fix this:

In ideal case, results would be ordered by date of on-chain discovery, just like block frost does it, so that first returned address would be first address that was ever found in chain. This address is most likely belonging to wallet owner as it's very unlikely hacker would know staking key of some wallet that was never used on-chain. Simply make it so that this query https://github.com/cardano-community/guild-operators/blob/koios-1.0.7/files/grest/rpc/account/account_addresses.sql is ordering addresses by some column that related to time of their on-chain discovery (could be even ID of address if it's serial - I am not familiar with the DB structure).

rdlrt commented 2 years ago

Thanks for creating the issue. Happy to apply the solution (which is essentially adding ORDER BY id on the query) - or get PR if you'd like to create one, but I would like to highlight that this does not guarantee to address protocol/design issue for staking wallets (against Frankenstein addresses) built on cardano.

In general, one should not assume addresses sharing an account belong to same wallet (even if using first address - while it will likely reduce the footprint) , protocol itself does not know of the formation of a 'wallet' which is essentially an off-chain mechanism created for UX. Thus, there is no accurate/guaranteed way to pull a HD-wallet information from chain except deriving addresses from account's (not stake address , but wrt HD-wallet's heirarchy) pub key.

We'll apply the change requested regardless 👍🏻

benapetr commented 2 years ago

Yes it doesn't 100% fix it, but it still improves the security by order of magnitude.

rdlrt commented 2 years ago

@benapetr - should be resolved in 013ad62