0ad (4), aranym, ardour, argo-cd, aria2, azahar, bcoin, bind9, btcpayserver (3), bullet3. Mix of CWE-407 and CWE-312.
2.5 KiB
bcoin — CWE-407 Disclosure Brief (bcoin-0001)
2026-04-13 · Patch available — awaiting upstream merge
Finding
One O(H*T) defect in bcoin's RPC layer. gettxoutproof calls block.hasTX(hash) per requested hash, where hasTX does an O(T) linear scan over block transactions. Fix: build a BufferSet for O(1) membership testing.
The Defect
bcoin-0001 (PATCHED — MEDIUM): lib/node/rpc.js:1032
// In RPC.getTxOutProof():
for (const hash of hashes) {
if (!block.hasTX(hash)) {
throw new RPCError(errs.VERIFY_ERROR,
'Block does not contain all txids.');
}
}
hashes contains H transaction hashes the caller wants a Merkle proof for. block.hasTX(hash) performs an O(T) linear scan over all T transactions in the block. Total cost: O(H*T). For a full Bitcoin block with T=3000 transactions and H=100 requested proofs, this performs 300,000 buffer comparisons.
Complexity Proof
At H=100 requested hashes, T=3000 transactions per block:
- Defective: 100 × 3000 = 300,000 buffer comparisons
- Fixed: T=3000 set construction + 100 O(1) lookups = ~3,100 operations
- ~97× op reduction.
Impact
bcoin is a full Bitcoin node implementation in JavaScript. gettxoutproof is an RPC endpoint used by wallets, block explorers, and SPV verification tools. Large blocks (post-SegWit) routinely contain 3000+ transactions. High-frequency RPC callers requesting multiple proofs per block hit the quadratic path repeatedly.
The Fix
Build a BufferSet from block transactions for O(1) membership testing:
// Before
for (const hash of hashes) {
if (!block.hasTX(hash)) { ... }
}
// After
// CWE-407 fix: BufferSet for O(1) membership instead of O(T) hasTX scan.
const txSet = new BufferSet();
for (const tx of block.txs)
txSet.add(tx.hash());
for (const hash of hashes) {
if (!txSet.has(hash)) { ... }
}
Patch
Fix available: defects/bcoin/patch/bcoin-0001-rpc-gettxoutproof-linear-scan.patch
Single-file patch on lib/node/rpc.js. Adds BufferSet construction before the validation loop.
What We Ask
A patch is ready for review.
- Confirm receipt and assign a GitHub issue reference (bcoin-org/bcoin).
- Assess severity — fires on every
gettxoutproofRPC call with multiple hashes. - Coordinate a disclosure date — we target 90 days from first contact.
- We will credit the bcoin team in the public disclosure. Preferred acknowledgment format welcome.
Contact: see cover email. This brief is confidential until coordinated disclosure.