Forgery Attack on Unbalanced Merkle Trees #87
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
edited-by-warden
🤖_30_group
AI based duplicate group recommendation
Lines of code
https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/6f861c85b281a29f04daacfe17a2099d7dad5f8f/src/challengeV2/libraries/MerkleTreeLib.sol#L110
Vulnerability details
Impact
consensus issues,denial of service attacks,double spending attack.
Proof of Concept
https://github.com/code-423n4/2024-05-arbitrum-foundation/blob/6f861c85b281a29f04daacfe17a2099d7dad5f8f/src/challengeV2/libraries/MerkleTreeLib.sol#L110
The
root
function assumes that the provided Merkle expansion represents a balanced Merkle tree by calculating the root hash to non-zero values at each level but there's no check for checking if the provided Merkle tree is balanced or unbalancedHere's a test function in MerkleTreeLib.t.sol
How it works:
Unbalanced Merkle Tree Construction:
Unbalanced Merkle tree with an odd number of leaf nodes (7 as demonstrated in the test function), the leaf nodes are represented as hashes of transactions.
leaves = [h1, h2, h3, h4, h5, h6, h7]. To construct the Merkle tree, the last leaf node h7 is duplicated to ensure that every non-leaf node has two children.
h12 h34
/ \ /
h1 h2 h3 h4
/ \ /
h5 h6 h7 h7
Here the hashes at each level is identical to the unbalanced tree after duplicating the last leaf node.
Forging a Balanced Merkle Tree:
An attacker can forge a balanced Merkle tree with 8 leaf nodes by duplicating the last leaf node h7 to create balanced tree: forgedLeaves = [h1, h2, h3, h4, h5, h6, h7, h7].
h12 h34
/ \ /
h1 h2 h3 h4
/ \ /
h5 h6 h7 h7
Here, the structure and the hashes at each level are identical to the unbalanced tree after duplicating the last leaf node resulting the same root hash as the original unbalanced tree, duplication of the last leaf node in the unbalanced tree (h7) allow the forged balanced tree with the same root hash.
Both trees end up with the same root hash because the structure and the hashes at each level is the same after the duplication of the last leaf node.
Sources:
HarryR/panautomata#4
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2012-August/001806.html
Tools Used
Manual review
Recommended Mitigation Steps
Consider adding a check in the
root
function to ensure that the provided Merkle tree is balanced by comparing the expected size of a balanced treewith the actual size calculated using the treeSize function.
Assessed type
Invalid Validation
The text was updated successfully, but these errors were encountered: