|Name||Symbol||Price (USD)||Price (EUR)||Price (BTC)||Market Cap||Daily Attack Cost (USD)||Daily Attack Cost (EUR)||Daily Attack Cost (BTC)|
Zcash Protocol-Level Denial-of-Service (CVE-2019-11636)
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.
DetailsThe 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 MarketThe 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:
- All/most pools will not mine a transaction larger than 1MB, though according to the Zcash protocol and codebase, they are allowed. This may have the unintended effect of taking less CPU-time to fill a block.
- All/most pools will de-prioritize large transactions with the default transaction fee
- Paying a double (or more) transaction fee will make large transaction get mined in the next block, i.e. a fee market exists
Proof-of-ConceptThe PoC will not be shared at this time due to the likelihood it would be used for evil instead of good.
MotivationThe 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.
DonationsThis 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:
- BTC 1Doe7xSpGTv2mWqZHCgdwAGJNkRd58FpMw
- XMR 43SXJRKUSmQN4rShR4RFf7VNtz4YDxfY2gPrgtizqEUj5JgfWQzp6SdMcGyCUrswqKiQ5B32vbS3cC2b9Er5bUMMCg67qMg
- ZEC zs103kdaehwd6rr65fqyk9vvchjd3j0d8a344fscnsyusg2a3nwhucadw9ejj6ufmyh5k96v8qgpgd
- ZEC t1a58BR8K216G2oUNSwm4PCGxp7Q9mFKMSx