Sapling Woodchipper CVE-2019-11636

View on GitHub
Name Symbol Price (USD) Price (EUR) Price (BTC) Market Cap Daily Attack Cost (USD) Daily Attack Cost (EUR) Daily Attack Cost (BTC)
Zcash ZEC
Powered by Coingecko API

Zcash Protocol-Level Denial-of-Service (CVE-2019-11636)

Sapling Woodchipper

Sapling Woodchipper Loves Supple Saplings

The Sapling Woodchipper is a protocol-level Denial-of-Service against any cryptocoin which implements the Zcash 2.x Sapling protocol, most notably Zcash (ZEC) itself.

The exact severity of the DoS depends on the exact chain parameters of each coin, specifically maximum transaction size and maximum block size.

The Sapling Woodchipper is spiritually similar to the Slowloris attack, in that one or a few machines can completely disable much more powerful entity in a vastly asymmetric attack. In this analogy, long-lived HTTP connections become extremely large transactions, and instead of taking down a webserver, making it unable to process requests, a blockchain is completely filled to the point that no normal users can make transactions. This is a very focused attack, like the Slowloris. Unlike the Slowloris attack, the Sapling Woodchipper is very CPU intensive, and as such, the attack benefits greatly from more powerful CPUs. In this sense, the Sapling Woodchipper takes a lot more work than Slowloris, which merely waits the maximum time before successfully ending a request.

Sapling Woodchipper has been assigned CVE-2019-11636.

Details

The code change which enables the Sapling Woodchipper was merged via Zcash Pull Request 3212 and requested as a feature in Zcash Issue 2864. It relates to the consensus rule about maximum allowed transaction size:
-static const unsigned int MAX_TX_SIZE = 100000;
+static const unsigned int MAX_TX_SIZE_BEFORE_SAPLING = 100000;
+static const unsigned int MAX_TX_SIZE_AFTER_SAPLING = MAX_BLOCK_SIZE;
From src/consensus/consensus.h: Previously transactions could be at most 100KB in size but after Sapling activation, transactions can fill an entire block! This means that to fill all 576 daily Zcash blocks, one must only pay a single transaction fee per block, or a fixed cost of 0.0576 ZEC/day to fill all blocks. The following one line patch is the simplest mitigation to the Sapling Woodchipper, which goes back to the previous 100KB limit. It increases attack cost by roughly 10X-40X depending on blocksize.
// in src/consensus/consensus.h
-static const unsigned int MAX_TX_SIZE_AFTER_SAPLING = MAX_BLOCK_SIZE;
+static const unsigned int MAX_TX_SIZE_AFTER_SAPLING = 100000;
Here is an example transaction which is 996827 bytes (0.95MB) and includes over 1000 JoinSplits: ZEC transaction 9409c0f6. If an attacker has a CPU with a single core that can do ~1000 JoinSplits in less time than the block time of the coin, i.e. 150 seconds for ZEC, then a single core of a single computer can flood the network with transactions and pay the absolute minimum attack cost of 0.0576 ZEC/day. For attackers with slower CPUs, they must use more machines in the attack, and pay more transaction fees. According to Github Issue 3983: "Note that Sapling Output proofs can be reused for multiple output notes, allowing transactions to be inflated to any desired size at low computational cost." which means that the Sapling Woodchipper could be made drastically more efficient, by re-using the same data across all ~1000 JoinSplits instead of recomputing it.

Zcash Fee Market

The actions of Zcash mining pools make it very clear that a "shadow" Zcash fee market exists. This makes perfect sense for miners and mining pools, but it seems that various Zcash people, up to and including the CEO, would prefer to tell people that no fee market exists on the Zcash network. According to the Zcash Wallet Developer UX Checklist:
Disable users from setting their own transaction fees

Do not allow users to customize fees.
Our network is fast enough that mining incentivization is not an issue.
Unique transaction fees can cause linkability within transactions, especially for zaddrs.
This is mis-guided and wrong. The author discovered some interesting information about Zcash mining pools during the research of this CVE: The author recommends Zcash and all source code forks of Zcash migrate to variable fees based on transaction size, to fully mitigate transaction-based Denial-of-Service attacks. Additionally, GUI wallets should be smart enough to know what current network fee conditions are, and give users a reasonable choice of paying different fees for confirmations in different timeframes, just like modern Bitcoin wallets.

Official Site

https://saplingwoodchipper.github.io

Proof-of-Concept

The PoC will not be shared at this time due to the likelihood it would be used for evil instead of good.

Motivation

The motivation for this CVE is to make the Zcash protocol, source code and network more secure. It was discovered in October 2018 while studying how the HushList protocol could be updated to use Sapling transactions.

Author

Duke Leto Keybase @dukeleto

Donations

This work was funded purely by the author, no grants or funding were received to fund this research. If you would like to support future cryptocoin security research, these addresses are available: