Reducing the risk of catastrophic cryptocurrency bugs
We shared an account of how Cory Fields, a Bitcoin Core developer at the MIT Digital Currency Initiative, found and disclosed a chain-split vulnerability affecting Bitcoin Cash. (This has been patched; the Bitcoin Cash codebase no longer has this vulnerability).
This post adds a bit more context about what makes the cryptocurrency space overall so interesting (and dangerous) when it comes to vulnerabilities and describes some proactive measures that can be taken to aid in their detection, disclosure and mitigation.
Facilitating responsible disclosure
Cory’s description of the frustrating process of submitting an anonymous responsible disclosure report is quite common. Natalie Silvanovich from Google’s Project Zero recently shared a similar experience with a disclosure to Samsung. The roadblocks are different in that case, but the theme is the same: many projects do not follow established best practices, making it difficult to do the right thing.
For projects without an established and functional disclosure protocol, it is only a matter of time before a bug like SIGHASH_BUG will be weaponized instead of reported. Projects should take steps to ensure that responsible disclosure is the easiest, safest and most lucrative response. This means, at minimum:
- Having a clearly documented procedure for responsible disclosure, including an email address for reporting potential issues
- Providing encryption keys for well-known developers and committing them to the code repository as well as public key servers
- Quickly responding to reports, even from anonymous sources
- Awarding bug bounties worth a multiple of the black-market value of the exploits
Considering faithful validation in the incentive model
Tadge Dryja, another developer at the DCI, has described Bitcoin as “the currency of enemies,” presumably because the entire system is intended to work even when all participants in the system actively distrust each other. Many other cryptocurrencies aim for the same “trustless” model. Some trust is still employed in this setting, however: trust that the entire software stack you’re running is working as advertised, and doesn’t have bugs.
Having consistently working-as-advertised validation software is a part of a cryptocurrency’s incentive model. Users are incentivized to use conforming software or risk being split from the correct chain. But there’s a clear pitfall in that line of thinking: We can’t expect all users to assess for themselves whether or not the program they’re running is working as advertised.
A cryptocurrency’s resiliency comes from a design that tolerates people in the system acting in their own self-interest. A reasonable approach to defending against unfaithful validation would be to ensure that potential attackers are incentivized to responsibly disclose vulnerabilities rather than weaponize them. Put that way, the flaw in the current system is clear: Disclosure is the least lucrative of all options.
We won’t speculate here as to how vulnerability disclosures should be rewarded, other than to say that if weaponizing a cryptocurrency exploit could yield a return of millions of dollars, with many stakeholders standing to lose millions or billions as a result, we would expect stakeholders to be interested in establishing and funding bounty programs similar to those created by Ethereum, Tezos and EOS. It’s surprising that more haven’t done so already.
Chain-split policies and proactive monitoring
In the event of an accidental chain-split, large merchants, miners, exchanges and other custodians should take appropriate action within an hour and ideally less. The actions taken should follow each party’s pre-set and publicly available chain-split policy, leaving little room for surprises. The most likely action for all parties would be to halt activity, report the issue, and aid in the process of finding and fixing it.
In order to be proactive against bugs in software upgrades, large stakeholders should run old and new versions simultaneously to ensure that they agree.
Users should avoid any service without a chain-split policy or proactive monitoring. Implementing this isn’t too hard to do, and the benefits far outweigh the costs. Here’s an example of a tool which does just that.
Defensive coding and review
A cryptocurrency’s exchange value is partially a reflection of the faith that its developer community won’t introduce catastrophic bugs. An inexperienced development team is a significant liability. Cryptocurrency development is quite difficult, and in a different way than developing other systems software. The traditional distributed consensus literature doesn’t really address the idea of having validation rules — in cryptocurrencies, a node will never accept as valid a chain that violates the rules it is following, no matter how much proof of work or how many signatures are on it.
Because every change to a line of code has the potential to cause a chain split, some of the best practices in cryptocurrency development violate commonly accepted programming best practices. For example, some developers would prefer to copy and paste code rather than refactor it to avoid running the risk of an accidental behavioral change in the refactored code. As another example, counter to standard practice, it is critically important to avoid outsourcing to external libraries for validation. Bitcoin developers learned this the hard way. It takes years for many developers to come around to the defensive mindset required for this type of programming. It’s just different. Right now, the tools we have for building and maintaining cryptocurrencies are inadequate, so we have to fall back on a thorough manual code review.
Quality testing and review takes time. Users should be wary of projects that accept changes, especially to consensus code, without adequate expert review.
Areas for future research
Defensive coding and extensive review can only take us so far. At some point, we will need to develop new tools. These could help eliminate entire classes of bugs for cryptocurrencies. As an example, a helpful tool would be one that can be used to prove that the behavior of refactored code has not changed. A theoretical compiler and linker could combine multiple software versions such that they execute simultaneously, deferring to the older version’s results for a certain amount of time. Formal verification tools could be devised to ensure that a script interpreter is behaving as intended. It may even make sense for entirely new niche programming languages to evolve for implementing cryptocurrencies safely.
It is important that cryptocurrency developers remain vigilant against bugs like SIGHASH_BUG, but it is also vital that we also continue to actively research new technology that may one day prevent them entirely. There has been an explosion of cryptocurrencies in the last year. While the experimentation is exciting, users and investors should demand that cryptocurrencies develop and follow best practices, even if cloning a well-known codebase. The DCI wants to help the space move forward. Stay tuned for more from us on cryptocurrencies and security.