Headline
CVE-2023-34459: Merge pull request from GHSA-wprv-93r4-jj2p · OpenZeppelin/openzeppelin-contracts@4d2383e
OpenZeppelin Contracts is a library for smart contract development. Starting in version 4.7.0 and prior to version 4.9.2, when the verifyMultiProof
, verifyMultiProofCalldata
, procesprocessMultiProof
, or processMultiProofCalldat
functions are in use, it is possible to construct merkle trees that allow forging a valid multiproof for an arbitrary set of leaves.
A contract may be vulnerable if it uses multiproofs for verification and the merkle tree that is processed includes a node with value 0 at depth 1 (just under the root). This could happen inadvertedly for balanced trees with 3 leaves or less, if the leaves are not hashed. This could happen deliberately if a malicious tree builder includes such a node in the tree.
A contract is not vulnerable if it uses single-leaf proving (verify
, verifyCalldata
, processProof
, or processProofCalldata
), or if it uses multiproofs with a known tree that has hashed leaves. Standard merkle trees produced or validated with the @openzeppelin/merkle-tree library are safe.
The problem has been patched in version 4.9.2.
Some workarounds are available. For those using multiproofs: When constructing merkle trees hash the leaves and do not insert empty nodes in your trees. Using the @openzeppelin/merkle-tree package eliminates this issue. Do not accept user-provided merkle roots without reconstructing at least the first level of the tree. Verify the merkle tree structure by reconstructing it from the leaves.
@@ -1,11 +1,8 @@ require(‘@openzeppelin/test-helpers’);
const { expectRevert } = require(‘@openzeppelin/test-helpers’); const { expect } = require(‘chai’); const { MerkleTree } = require(‘merkletreejs’); const keccak256 = require(‘keccak256’);
const { expect } = require(‘chai’);
const MerkleProof = artifacts.require(‘$MerkleProof’);
contract('MerkleProof’, function () { Expand Down Expand Up @@ -176,5 +173,28 @@ contract('MerkleProof’, function () { expect(await this.merkleProof.$multiProofVerify([root], [], root, [])).to.equal(true); expect(await this.merkleProof.$multiProofVerifyCalldata([root], [], root, [])).to.equal(true); });
it('reverts processing manipulated proofs with a zero-value node at depth 1’, async function () { // Create a merkle tree that contains a zero leaf at depth 1 const leaves = [keccak256(‘real leaf’), Buffer.alloc(32, 0)]; const merkleTree = new MerkleTree(leaves, keccak256, { sortPairs: true });
const root = merkleTree.getRoot();
// Now we can pass any ** malicious ** fake leaves as valid! const maliciousLeaves = ['some’, 'malicious’, ‘leaves’].map(keccak256).sort(Buffer.compare); const maliciousProof = [leaves[0], leaves[0]]; const maliciousProofFlags = [true, true, false];
await expectRevert( this.merkleProof.$multiProofVerify(maliciousProof, maliciousProofFlags, root, maliciousLeaves), 'MerkleProof: invalid multiproof’, );
await expectRevert( this.merkleProof.$multiProofVerifyCalldata(maliciousProof, maliciousProofFlags, root, maliciousLeaves), 'MerkleProof: invalid multiproof’, ); }); }); });
Related news
### Impact When the `verifyMultiProof`, `verifyMultiProofCalldata`, `processMultiProof`, or `processMultiProofCalldata` functions are in use, it is possible to construct merkle trees that allow forging a valid multiproof for an arbitrary set of leaves. A contract may be vulnerable if it uses multiproofs for verification and the merkle tree that is processed includes a node with value 0 at depth 1 (just under the root). This could happen inadvertently for balanced trees with 3 leaves or less, if the leaves are not hashed. This could happen deliberately if a malicious tree builder includes such a node in the tree. A contract is not vulnerable if it uses single-leaf proving (`verify`, `verifyCalldata`, `processProof`, or `processProofCalldata`), or if it uses multiproofs with a known tree that has hashed leaves. Standard merkle trees produced or validated with the [@openzeppelin/merkle-tree](https://github.com/OpenZeppelin/merkle-tree) library are safe. ### Patches The problem has be...