Penetration Test Report (Coinspect): CoinspectReportZcash2016

Source Code Review
Prepared for Zcash • October 2016
V1.5
1. Table of Contents
1. Table of Contents
2. Executive Summary
3. Introduction
3.1. Scope
4. Summary Of Findings
5. Findings
ZCA-001 - DoS attack if orphan JoinSplit transactions are enabled
ZCA-002 - Inheriting FindAndDelete from Bitcoin is considered dangerous
ZCA-003 - scriptSig malleability allows 51% attack by invalidating honest miners blocks
ZCA-004 - Decrease in huge-reorg security margin
ZCA-005 - Unlimited number of transaction proofs allows CPU-exhaustion attacks
ZCA-006 - Erroneous nValueOut range check allows CPU-exhaustion attacks
ZCA-007 - Forever growing nullifier set will end up being stored in nonvolatile memory
ZCA-008 - Forever growing commitment tree slows down commitment lookup
ZCA-009 - Improper destination path validation in RPC calls allows arbitrary command
execution
ZCA-010 - Improper destination file permissions check in RPC calls could expose secret
keys
ZCA-011 - Information exposure through log files
6. Opportunity to fix Bitcoin’s known problems
6.1. Remove the distinction between mandatory and nonmandatory input validation flags
6.2. Add a block height field directly to header (apart from the coinbase field)
6.3. P2SH using scriptSig that is not a script is an aberration of nature
6.4. Add script versioning
6.5. Move the height field in the coinbase script field to the coinbase prevout hash field
6.6. Mask out the must-be-zero bits in the previous-block-hash (block header) so miners
can reuse them for nonce space
6.7. Allow adding additional inputs to generation transactions
6.8. Include value of TxOut being spent in signature hash
6.9. Prevent O(n2) hashing attack by serializing only the hashes of inputs and outputs
6.10. CHECKMULTISIG popping one-too-many items off the stack
6.11. Extended Scripts opcodes can be enabled, after security audit
6.12. Include the maximum size of a scriptSig or transaction for each input signature
2. Executive Summary
Between August and October 2016, Zcash engaged Coinspect to perform a security audit of
​ ​ ​ ​
their implementation of the Zerocash protocol. The objective of the audit requested by Zcash
​ ​
was to evaluate the security of Zcash's innovations over the Bitcoin Core source code.
​ ​
During the assessment, Coinspect identified 2 high-risk issues, 3 medium-risk issues, and 6
​ ​ ​ ​ ​
low-risk issues. The high-risk issues identified during the assessment are not remotely
exploitable by themselves to steal funds or compromise the privacy Zcash users. The high-risk
and moderate-risk issues identified affect the performance and availability of the p2p network.
3. Introduction
Zcash is an implementation of the Zerocash protocol based on the Bitcoin Core C++ code. It
intends to offer a far higher standard of privacy and anonymity through a sophisticated
zero-knowledge proving scheme which preserves confidentiality of transaction metadata.
A whitebox security audit was conducted on the Zcash source code in order to detect security,
​
privacy, and availability related problems. Coinspect reviewed Zcash changes to Bitcoin Core,
including their interaction with other parts of the Bitcoin protocol and other parts of the
implementation.
The present report was completed on October 1st by Coinspect and includes results from the
first and second phase of the audit.
3.1. Scope
The Zcash auditing strategy tasked experts with different specializations to focus on different
​ ​
aspects of the system.
The objective of the first phase of the audit requested Coinspect to review changes to the
Bitcoin Core code, focusing on the “core consensus” pieces. The review included but was not
​ ​
limited to the following checks:
● JoinSplit operations ● Input validation
● Transaction validation ● Denial of service prevention
● Founder's Reward ● Integer overflows
● Block header changes ● New data structures
● Transaction signing ● Cryptographic weaknesses
© 2016 Coinspect 1
The objectives of the second phase of the audit included:
● New RPC interface
● Wallet encryption
● Founder’s Reward address rotation
● Information disclosure
● Changes made to the consensus code after the first phase concluded.
The audit conducted by Coinspect did not include: the zkSNARK cryptographic scheme, the
libsnark implementation, or Equihash design.
© 2016 Coinspect 2
Source Code Review
4. Summary Of Findings
ID Description Risk
ZCA-001 DoS attack if orphan JoinSplit transactions are enabled Low
ZCA-002 Inheriting FindAndDelete from Bitcoin is considered dangerous Medium
ZCA-003 scriptSig malleability allows 51% attack by invalidating honest miners High
blocks
ZCA-004 Decrease in huge-reorg security margin Low
ZCA-005 Unlimited number of transaction proofs allows CPU-exhaustion attacks Medium
ZCA-006 Erroneous nValueOut range check allows CPU-exhaustion attacks High
ZCA-007 Forever growing nullifier set will end up being stored in nonvolatile Low
memory
ZCA-008 Forever growing commitment tree slows down commitment lookup Low
ZCA-009 Improper destination path validation in RPC calls allows arbitrary Medium
command execution
ZCA-010 Improper destination file permissions check in RPC calls could expose Low
secret keys
ZCA-011 Information exposure through log files Low
© 2016 Coinspect 3
5. Findings
ZCA-001 DoS attack if orphan JoinSplit transactions are enabled
Category Availability
Total Risk Low | Impact: High | Likelihood: Low1 ​ | Effort to Fix: Medium
​ ​
-1- Low, as orphans with JoinSplits are currently disabled
​ ​
Description
Initial expensive verifications in transaction checking allow a DoS attack if orphan transactions
with JoinSplits are enabled. In Bitcoin a transaction is checked in stages, first all non-expensive
operations and finally signatures are verified. This is to prevent a DoS attack discovered circa
2012 that could be amplified by using orphan transactions. Orphan transactions must be
detected using the least amount of CPU. If an orphan transaction X is stored in mapOrphans
and X depends on an output of the transaction Y and an output of the transaction Z, both
missing; then when Y enters the memory pool the reprocessing of X will be triggered. Since X
still depends on the missing Z, the transaction will not be evicted from mapOrphans. An attacker
can therefore make 10,000 transactions X(i) having vjoinsplit proofs, where each X(i) references
a set of 20 single-output transactions { Y(i) } and an output of the transaction Z. The attacker
sends all X(i) transaction to a victim node. The node will store all X(i) as orphans. Then the
attacker sends all transactions Y(i). Each Y(i) will trigger the re-verification of all X(i)
transactions. If validation of each vjoinsplit proof takes 10 msec, then for each transaction Y(i)
received by the victim node, it has to spend 100 seconds of processing all dependant X(i)
transactions. The attack finishes when all Y(i) transactions have been sent; transaction Z is
never sent. The result, in this example, is that the victim node is forced to process transactions
for 33 minutes.
Recommendations
Possible Solutions:
● Check vjoinsplit proofs as the last step of transaction validation.
● Create a proof validation cache.
● Never enable storage of orphan transactions with vjoinsplit proofs.
© 2016 Coinspect 4
ZCA-002 Inheriting FindAndDelete from Bitcoin is considered
dangerous
Category Availability
Total Risk Medium | Impact: High | Likelihood: Low | Effort to Fix: Low
​
Location src/script/interpreter.cpp:EvalScript()
CScript::FindAndDelete()
Fix Pull #1458
​
Description
Early Bitcoin implementations used a different scripting evaluation system, involving the
concatenation of scriptPub and scriptSig, and then executing the resulting script. That old
system was replaced by the current system, where the two scripts are evaluated one after the
other using the same stack. However, two software relics from those times were dragged until
today: the CODESEPARATOR opcode and the removal of the signature from the script prior