Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix DoS attack on cw20-escrow #19

Closed
ethanfrey opened this issue Jul 6, 2020 · 0 comments · Fixed by #20
Closed

Fix DoS attack on cw20-escrow #19

ethanfrey opened this issue Jul 6, 2020 · 0 comments · Fixed by #20

Comments

@ethanfrey
Copy link
Member

I wrote a simple, straight-forward escrow contract to demo and also propose as a bug hunting challenge for the online workshop. Here is the issue with the original implementation.

We allow anyone to "top up" the contract, which is fine with native tokens. However, it opens up a DoS attack surface. If I Receive(ReceiveMsg::TopUp{}) from a public key address (or any contract that doesn't implement Cw20HandleMsg::Transfer, then when I approve or refund the escrow and try to release funds, this message will return an error and thus abort the entire contract (other funds also remain locked). Since anyone can do this, it allows people to freeze funds in an escrow, even if they cannot steal them.

One approach would be to check if this address is a valid contract, but that is quite hard. It could be a slightly modified cw20 token contract that works perfectly, except on Transfer is the sender == escrow_contract && height > xyz (where xyz is a block or 2 ahead of the top-up call). Thus, there is no way to programatically ensure that arbitrary tokens are valid.

We could also permission top up, so only the original sender could add tokens. But this then gives them a revenge chance, of locking up the escrow before it was released to the proper recipient. They don't get the funds, but they can prevent the recipient from getting them too.

The only clean design I can think of is providing a whitelist of valid cw20 token contracts on Create. This is by default empty if creating with native tokens, or just the one cw20 token send on create if creating with cw20. You can also add an additional whitelist explicitly. The arbiter and recipient can review the list of tokens in the whitelist before accepting the escrow as valid payment, and if these are all valid addresses, TopUp can remain permissionless, while not allowing any more DoS vectors.

This issue and related PR should be references to this attack vector and a solution to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant