Terms and Conditions
- I agree to the Grant Agreement terms if funded
- I agree to Provide KYC information if funded above $50,000 USD
- I agree to disclose conflicts of interest
- I understand that this grant program is only eligible for completed work, as it is a retroactive grant program. Applications for planned or partially completed work will not be considered. All completed work will be verified and accepted by its intended users or their representatives, who will confirm that the outputs meet the required quality, functionality, and usability before the work is listed as an option for Coinholder voting.
- I agree that for any new open-source software, I will create a CONTRIBUTING.md file that reflects the high standards of Zcash development, using the
librustzcashstyle guides as a primary reference. - I understand when contributing to existing Zcash code, I am required to adhere to the project specific contribution guidelines, paying close attention to any merge, branch, pull request, and commit guidelines as exemplified in the librustzcash repository.
- I understand all grants are valued in USD but will be disbursed in Shielded ZEC. I acknowledge and accept that disbursement amounts may fluctuate based on the ZEC/USD exchange rate at the time of payment.
Application Owners (@octocat, @octocat1)
@janneh2000
Organization or Individual Name
j12s team, linceu.xyz.
Additional Team Members
N/A
How did you learn about the Lockbox: Coinholder Retroactive Grants Program?
Zcash Community Forum (Retroactive Grants category) and earlier retroactive applications for Zebra vulnerability disclosures.
Requested Grant Amount (USD)
$75,000
Category
Research & Development
Project Summary
I found and privately reported a High-severity denial-of-service in Zebra (GHSA-7jp4-mq53-4cvq): any connected peer could stall a node's verification with one crafted, unsigned transaction, at no cost and without being banned. The Zcash Foundation confirmed it, fixed it in zebrad 7.0.0, and published the advisory crediting me as the reporter.
Project Description
Zebra's mempool checks coinbase maturity once for every input a transaction spends. After the transaction newtype refactor in zebrad 6.4.0 (PR #10461), each of those checks rebuilt and cloned the transaction's whole output list, so verifying one transaction cost inputs × outputs. A transaction with about 24,000 inputs and 111,000 outputs (around 1.98 MB) took roughly 19 seconds of CPU on a 4-core machine.
The transaction needs no valid signatures and no funds. It spends existing unspent outputs with empty scriptSigs, and the maturity check runs before the standardness check that finally rejects it. That rejection carries a misbehavior score of 0, so the peer is never banned and can send it again, changing one byte to get past the reject cache. One connection can queue five of these at once, which on a 4–5 core node occupies the whole async runtime. Block verification, peer handling and sync stop while the attack runs, and the node recovers when it stops. No consensus rule or funds were at risk; this was a liveness problem.
Every node on zebrad 6.4.0, 6.4.1 and 6.4.2 (the mainnet releases at the time) and 7.0.0-rc.0 was affected in its default configuration, with no workaround.
I reported it privately through a GitHub security advisory with a working reproduction, kept the details private until the fix shipped and operators were notified, and offered to re-test the patch. The Zebra maintainers accepted the report, shipped the fix in zebrad 7.0.0 and published the advisory on 22 October 2026.
I'm applying here because there is no other way to be paid for this work. The Zcash Foundation does not pay for security reports outside a program, and ZCG's Security & Vulnerability Disclosure Initiative closed on 26 May 2026, before this report. ZCG asked researchers to keep reporting through private channels after the closure, and the Foundation has said the published advisory is the public record of the finding that anyone can cite.
Technical Approach (how you did it)
- Reviewed the zcash_primitives transaction newtype refactor (commit 8b91154, PR #10461) and found that Transaction::outputs() went from returning a borrowed slice to allocating a new Vec and copying every output script on each call.
- Traced the callers. coinbase_spend_restriction() always evaluates outputs() (it's the left operand of an ||), and tx_transparent_coinbase_spends_maturity() calls it inside the per-input loop even though the result only depends on the transaction, network and height.
- Confirmed reachability from the P2P path. In MempoolTxVerifier the maturity check runs after the UTXO lookups and before mempool_standard_input_scripts, so a transaction with empty scriptSigs pays the full cost and is then rejected as NonStandardInputs, which maps to misbehavior score 0. The work is synchronous inside the verification task, so the 73-second download timeout can't interrupt it.
- Wrote a Rust test that builds the transaction as real wire bytes and drives the production MempoolTxVerifier with a mock state service. Tested against v6.4.2 (e3eef2f) and main (a0c1f51).
- Used a scaling control to show the cost follows inputs × outputs rather than size. 4,000 × 40,000 took about 1.0 s; 24,000 × 111,000 took about 19 s (roughly 4× the inputs and 2.75× the outputs gave about 17× the time).
- Checked it against shipped advisories: it is not GHSA-4g24-549m-hp75 and not the #11353 fix.
- Proposed the fix: a non-allocating "has transparent outputs" check and hoisting the loop-invariant restriction out of the loop. I also flagged the same per-spend call on the block-commit path.
Time Period of Work Completion
October 2026 (research and private report filed on 10 October 2026; coordinated disclosure through advisory publication and the zebrad 7.0.0 release on 22 October 2026)
Total Budget (USD)
$75,000
Budget Breakdown
- Compensation:
- $(USD): 75,000
- Justification: Bounty-equivalent compensation for completed security research and coordinated disclosure. This is ZCG's own published base payout for a High-severity Core Node finding ($75,000). Zebra is a Core Node project under that table, and the Zcash Foundation rated this finding High (CVSS 7.5). The table also allowed a discretionary bonus of up to $37,500, which I am not requesting.
- Technology/Software:
- $(USD): 0
- Justification: Own hardware and open-source tools.
- Infrastructure/Hosting:
- $(USD): 0
- Justification: N/A
- Services/Contractors:
- $(USD): 0
- Justification: N/A
- Other:
- $(USD): 0
- Justification: N/A
- Total $(USD): 75,000
Previous Funding
No
Previous Funding Details
N/A
Other Funding Sources
No
Other Funding Sources Details
I have not received, and don't expect, payment from any other source for this finding. The Zcash Foundation does not pay for reports outside a program, and ZCG's vulnerability bounty closed on 26 May 2026, before this report.
Success Metrics
- The vulnerability was fixed before public disclosure: zebrad 7.0.0 (commit 08743d6), with the advisory and upgrade guidance published on 22 October 2026.
- The vulnerable check went from O(inputs × outputs) to O(inputs) per transaction. Before the fix, one ~1.98 MB transaction cost about 19 seconds of CPU on a 4-core machine.
- It protects every node that was on the 6.4.x line or 7.0.0-rc.0, which in default configuration had no workaround.
- The same fix also covered the per-spend pattern on the block-commit path, which my report flagged, and the per-signature SIGHASH_SINGLE check in zebra-script.
- It removed a free, unauthenticated and repeatable way for a single peer to stop a node from following the chain.
Proof of completion
- Repository/Commit:
- Fix commit 08743d6 - non-allocating transparent input/output checks; coinbase spend restriction computed once per transaction in the mempool and block-commit paths
- PR #10461 - the refactor that introduced the regression in 6.4.0
- Publication:
- GHSA-7jp4-mq53-4cvq - published by the Zcash Foundation on 22 Oct 2026, High (CVSS 3.1 7.5), reporter credit @janneh2000: "Thanks to @janneh2000 for reporting this with a reproduction against the production mempool verifier."
- CVE: not yet assigned (requested from the Zcash Foundation)
- Deployment/Release:
- Zebra v7.0.0 - Security section: "Fixed a quadratic CPU cost in transaction verification"
- Other Evidence:
- The original report and the reproduction test are in the advisory's private thread; the Zebra maintainers (ZFND Security) can confirm.
Conflict of Interest Disclosure
None. I'm an independent security researcher. I'm not employed by or affiliated with the Zcash Foundation, ZCG, FPF, ZODL, Shielded Labs or any keyholder organization. I also co-founded a DeFi security startup, which has no relationship with any Zcash organization or with this grant.
Community Forum Posting
- I understand it is my responsibility to post a link to this issue on the Zcash Community Forums after this application has been submitted so the community can give input. I understand this is required in order for the community to discuss and vote on this grant application. Note: If you are unable to post on the forum (for example, due to new user restrictions), please leave a comment below, and we will adjust your posting permissions.