For a little while it was possible to spend Bitcoin twice. Think of it like a coin on a string, you put it into the vending machine to get a delicious snack, but if you pull the string quickly enough you could spend it again on some soda too. Except this coin is worth something like eighty-grand.
On September 20, the full details of the latest fix for the Bitcoin Core were published. This information came two days after the fix was actually released. Two vulnerabilities were involved; a Denial of Service vulnerability and a critical inflation vulnerability, both covered in CVE-2018-17144. These were originally reported to several developers working on Bitcoin Core, as well as projects supporting other cryptocurrencies, including ABC and Unlimited.
Let’s take a look at how this worked, and how the network was patched (while being kept quiet) to close up this vulnerability.
What is Bitcoin Core and why should I care?
Bitcoin Core is an open source project which maintains and releases Bitcoin client software called “Bitcoin Core”. It’s a direct descendant of the original Bitcoin software client released by Satoshi Nakamoto after he published the famous Bitcoin whitepaper. The software is both a full-node, validating the blockchain, and a bitcoin wallet. Bitcoin Core has a huge reach as it is a popular full-node and many other node software is forked from this project.
So when a vulnerability arises affecting Bitcoin Core it usually makes a lot of people nervous. That was just what happened. A vulnerability in the code appeared, mostly because of a speed up optimization, which ended up making the backbone nodes susceptible to a denial of service and it was quickly found that this caused the double spending bug.
How This Vulnerability Could Be Used
Part of the threat here is one of trust in the network. An attacker could use this bug to cause older nodes to crash (version 0.14.x nodes) by creating a special block and pushing it to other nodes, thus creating a denial of service situation. By targeting important nodes (or a large number of nodes) in the manner, an attacker could trigger negative publicity for the Bitcoin network and cryptocurrencies in general.
But perhaps more interesting is the ability to conjure up non-existent bitcoin. It was possible to craft a special kind of block that would trick core software from versions 0.15.0 to 0.16.2 to accepting an invalid block. That fake block inflates the supply, appearing like you have twice the amount available while in actuality you’d be spending the same amount twice. Like a magician, half the coins have appeared out of thin air.
Scrambling for a Fix While Keeping Things Quiet
The time line of this bug is pretty demonstrative of the potential seriousness of the flaw. On September 17, around 15h00, the bug was anonymously reported. Three hours later both the DoS flaw and the inflation by double spending had been identified. By 22h00, patches were out. Over the next two days, the message was spread across public forums and mailing lists urging people to upgrade — but without disclosing the complete details, only the DoS condition was mentioned. Then, on September 20th, the flaw was identified fully by an independent researcher. By then, the Bitcoin Core team release the full details:
“In order to encourage rapid upgrades, the decision was made to immediately patch and disclose the less serious Denial of Service vulnerability, concurrently with reaching out to miners, businesses, and other affected systems while delaying publication of the full issue to give times [sic] for systems to upgrade. On September 20th a post in a public forum reported the full impact and although it was quickly retracted the claim was further circulated.”
It seems like the details would have been held back even longer if the vulnerability hadn’t been fully identified by a third-party. Of course we don’t know how much longer, but lately any rumour seems to lead to widespread cryptopanic, so this stance is understandable. This doesn’t mean I agree, it seems highly debatable, but that’s what happened. Nevertheless, the patch was produced and circulated in a matter of hours after the bug was known and this is something really worth noting. Working in this field I can assure you that this happens around 0.001% of the time. Yes… it’s an optimistic figure.
Double Spending and the Patch That Stopped It
Double spending immediately got me curious, who doesn’t want free cryptocurrency created from (even more) thin air? So I headed out to Bitcoin Core website and downloaded both the patch and unpatched versions to diff them and try to make some sense of what went wrong.
Luckily there were not so many code changes and the main part of the fix seemed to be surprisingly simple:
I’m not going to pretend that I went through some painful ~500k lines of C++ code, I just went over the changes and read a bunch of functions. But for those who want a really deep dive, check out the very detailed explanation by Jimmy Song.
The little code I actually read quickly reminded me of my hate/love relation with C++ and my occasional wonder of why it doesn’t just die… I know, I know…
At first glance it seems the bug was introduced in a negligent way, just to gain some speed. But after reading the whole detailed explanation, the conclusion is that a mistake was made in thinking a check was redundant and that it could be optimized out. This conclusion was incorrect.
So… Did Anyone Get Free Coins?
It doesn’t seem realistic that anyone would have been able to get free coins from this exploit. The fact is that this flaw sounds way worse in theory than it is in practice. In order to actually trigger a DoS or double spending attack, there is a cost of create a malicious block with sufficient proof-of-work because that requires the same amount of energy/mining equipment as finding a valid block. We are talking about a minimum of 12.5 BTC (around $82500 at today’s rates) to implement the attack and even then the attack was going to be noticed by different parties involved in the Bitcoin network. You’ve got to spend money to make money, but here an attacker would most likely ended up losing coins. As for cryptopanic created, that’s hard to measure.
Update Early, and Update Often
At this time there are already over 33% of the nodes running patched versions that supposedly equate to over half of the Bitcoin hashrate, since the top mining pools and exchanges were alerted first, with most mining nodes patched within hours on the first day. As far as we know, there were no attempts to exploit this vulnerability in the wild.
As technologies and software mature, there are always going to be bugs. In a piece of critical software, the decisions made after knowing the existence of such bugs are of paramount importance to deter potential attacks and protect the final user. In the end, it seemed that the Bitcoin network had a really close call and the quick action by the developers solved the issue before it could become a problem, even if it was only bad PR.
On the other hand, the way the information was withhold makes me uncomfortable. What do you think about it, was this disclosure handled correctly?