code-423n4 / contracts

Code4rena contracts
32 stars 6 forks source link

Merkle proof implementation is subject to tree extension attacks #39

Closed Austin-Williams closed 2 years ago

Austin-Williams commented 2 years ago

The merkle proof code does not check the length of the proofs, and so it is susceptible to a tree-extension attack (or second-preimage attack).

While this same code has been used in other projects, the key difference here is that the leaf nodes (recipient addresses) have been chosen by wardens (potential adversaries), whereas in other projects the leaf nodes are addresses grabbed from historical blockchain data (not chosen by potential adversaries).

This means a malicious airdrop receiver could have given you a malicious bytes32 "address" which is actually its own merkle root for a tree of addresses that the attacker controls. If you used such a malicious address as a leaf in your merkle tree, it would allow the attacker to generate arbitrarily many valid proofs for addresses they control.

After computing your merkle tree and learning its depth -- and before deploying these contracts -- I recommend adding a require(merkleProof.length == treeDepth, 'invalid proof') just above this line.

MrToph commented 2 years ago

While this same code has been used in other projects, the key difference here is that the leaf nodes (recipient addresses) have been chosen by wardens (potential adversaries)

Good point but the leaf nodes are keccak(recipient, amount) where the claim amount has been chosen by the C4 team, does this prevent this?

If I understand your attack correctly, the attacker would do:

Austin-Williams commented 2 years ago

Ah okay! I was under the impression that the user-provided addresses were being used (directly) as leaves of the merkle tree.

As long as the leaves themselves aren't attacker-chosen, then that's fine. (It's even fine that they are attacker influenced in the way you mention above).

I think we're okay.

Austin-Williams commented 2 years ago

Okay, I'm sufficiently satisfied that an attacker could not get a "bad merkle root" as a leaf in the tree via the form submission.