Author: Optech
Source: https://bitcoinops.org/en/newsletters/2024/07/05/
This article is from the news section of Bitcoin Optech Newsletter #310. Translation provided by "Optech Chinese Translation Team ( BitcoinOptechCN )".
The original article summarizes the recently disclosed security vulnerabilities that affect versions of Bitcoin Core prior to 0.21.0. To help readers determine the security of the software version they are using, the descriptions of the vulnerabilities have been rearranged in reverse order of when they were fixed. Users of newer versions will have fewer sections that need to be read seriously and will have them placed at the front.
We are well aware that the soft fork philosophy is a core part of the Bitcoin development philosophy. It gives users the freedom to choose their favorite consensus rules. Therefore, the security of old versions of software is something that everyone should defend. Without it, the soft fork philosophy and its corresponding freedom are just empty talk. However, software, like other products, has a designed lifecycle. It is unrealistic to expect a software product to be permanently maintained for security. Therefore, in the end, full node operators must assume the responsibility of judgment: evaluate the security of a software before using it, and update their evaluation as information is disclosed.
Vulnerabilities affecting versions of Bitcoin Core prior to 0.21.0 : Antoine Poinsot posted a link in the Bitcoin-Dev mailing list, announcing 10 vulnerabilities affecting versions of Bitcoin Core software that have been retired for nearly two years. We summarize the disclosures as follows:
Network split due to excessive time adjustments : Old versions of Bitcoin Core allowed their clock to be distorted by the times reported by the first 200 peers it connected to. The code was intended to allow distortions of no more than 70 minutes. All versions of the Bitcoin Core software temporarily ignored blocks with timestamps that were more than 2 hours past the local time. The combination of two bugs allowed an attacker to set the victim's clock back more than two hours, causing it to ignore blocks with accurate timestamps. The vulnerability was dutifully disclosed by developer practicalswift and fixed in Bitcoin Core 0.21.0.
Reviewing unconfirmed transactions : Peers typically announce new transactions by the transaction's txid or wtxid. When a node first sees a txid or wtxid, it requests the full transaction from the first peer that announced the transaction. While waiting for this peer to reply, the node also tracks other peers that announced the same txid or wtxid. If the first peer does not reply and times out, the node requests the full transaction from the second peer (if it times out again, it turns to the third peer, and so on).
Prior to Bitcoin Core 0.21.0, nodes would only track a maximum of 50,000 requests. So, after announcing a txid, the first peer could delay responding to nodes' requests for full transactions until all of its peers had announced the transaction, and then send 50,000 announcements of other txids (which could all be fake). This way, after the node times out on its full transaction request to the first peer, it will not request full transactions from any other peers. The attacker (the first peer) can repeat this attack indefinitely, permanently blocking the node from receiving these transactions. Note that this censorship of unconfirmed transactions can prevent transactions from being confirmed quickly, which can lead to loss of funds in contractual protocols such as lightning channels. John Newbery responsibly disclosed this vulnerability, citing co-discovery from Amiti Uttarwar. The fix was released in Bitcoin Core 0.21.0.
CPU/Memory DoS due to Unlimited Ban List : Bitcoin Core PR #15617 (first included in 0.19.0) added code to check for locally banned IP addresses up to 2500 times when a P2P
getaddr
message is received. The length of a node's ban list is unlimited, and if an attacker controls a large number of IP addresses (for example, easily available IPv6 addresses), the list can swell to a large size. When this list becomes very long, eachgetaddr
request can consume excessive amounts of CPU and memory, potentially rendering the node unusable or even crashing. This vulnerability was tracked as CVE-2020-14198 and was fixed in Bitcoin Core 0.20.1.Memory corruption caused by attempts to parse BIP72 URIs : Bitcoin Core prior to 0.20.0 supported the BIP70 payment protocol , which extends the BIP21
bitcoin:
URI tor
an HTTP(S) URL using the protocol defined by BIP72 . Bitcoin Core would attempt to download the file from this URL and store it in memory pending parsing, but if the file was larger than available memory, Bitcoin Core would eventually terminate. While the attempted download occurred in the background, users could walk away and not notice the node crashing and not restart critical services. This bug was dutifully disclosed by Michael Ford and fixed in Bitcoin Core 0.20.0 by removing support for BIP70 (see WEB REPORT #70 ).Memory DoS from large
inv
messages : A P2Pinv
message can contain a list of up to 50,000 block header hashes. Prior to 0.20.0, modern Bitcoin Core nodes would reply with a separate P2Pgetheaders
message for each hash they did not understand, which was about 1 kB in size. This caused nodes to store about 50 MB of messages in memory, waiting for peers to receive them. Each peer could do this (and the default number of peers was about 130), which would use more than 6.5 GB of memory on top of the node's normal memory requirements - enough to crash many nodes. Crashed nodes might not be able to process time-sensitive transactions for users of the contractual protocol, potentially causing users to lose funds. John Newbery responsibly disclosed this vulnerability and provided a fix: reply to aninv
message with only a singlegetheaders
message, no matter how many hashes it contained; this fix went into Bitcoin Core 0.20.0.DoS via malformed requests that waste CPU : Prior to Bitcoin Core 0.20.0, an attacker or a malformed peer could send a malformed P2P
getdata
message that caused the thread processing the message to consume 100% of the CPU. For the duration of the connection, the node would no longer be able to receive messages from the attacker, although it could still receive messages from honest peers. For nodes with a few CPU cores, this might only cause minor problems; elsewhere it would become a nuisance. John Newbery responsibly disclosed this vulnerability and provided a fix that made it into Bitcoin Core 0.20.0.CPU DoS and node lags due to processing orphan transactions : Bitcoin Core nodes keep track of a cache of no more than 100 " orphan transactions " for which the node does not yet have the necessary parent transaction information in the mempool and UTXO set. After validating a new transaction, the node checks to see if any of the orphan transactions have become available for processing. Prior to Bitcoin Core 0.18.0, each time the orphan transaction cache was checked, the node would attempt to validate each orphan transaction using the latest mempool and UTXO state. If all 100 cached orphan transactions were constructed to require a large amount of CPU to validate, the node could waste excessive amounts of CPU and could be unable to process new blocks and transactions for hours. This attack is essentially free: orphan transactions can be created for free because they can reference parent transactions that do not exist. A stalled node will be unable to generate block templates, so this attack could be used to prevent a miner from earning revenue, and could be used to prevent transactions from being confirmed, potentially causing users of contractual protocols such as lightning channels to lose funds. Developer sec.eine dutifully disclosed the vulnerability; it was fixed in Bitcoin Core 0.18.0.
Memory DoS using low-difficulty headers : Since Bitcoin Core 0.10, nodes have requested that each of their peers send headers from the best blockchain they know of (the valid blockchain with the most accumulated proof-of-work). A known problem with this approach is that a malicious peer can bombard the node with a large number of fake headers of low difficulty (e.g., difficulty 1), which are easy to create with advanced ASIC mining equipment. Bitcoin Core's original solution was to only accept headers from blockchains that matched a checkpoint hardcoded into the code. The last checkpoint, although from 2014, had a relatively high difficulty by today's standards, so it would have required a lot of work to create the fake headers. However, a code change introduced in Bitcoin Core 0.12 began allowing nodes to accept low-difficulty headers into memory, potentially allowing an attacker to fill up memory with fake headers. This could cause nodes to crash and, by extension, cause users of contractual protocols such as Lightning channels to lose funds. Cory Fields responsibly disclosed this vulnerability; it is fixed in 0.15.0.
Remote code execution vulnerability due to miniupnpc : Prior to Bitcoin Core 0.11.1 (released in October 2015), nodes enabled UPnP by default to allow inbound connections through NAT . This was implemented using the miniupnpc library , which was found by Aleksandar Nikolic to have multiple remotely exploitable vulnerabilities ( CVE-2015-6031 ). These vulnerabilities were fixed in the upstream library, which also made it into Bitcoin Core, and the developers took an update to disable UPnP by default. While researching this bug, Bitcoin developer Wladimir J. Van Der Laan discovered another remote code execution vulnerability in the same library. This vulnerability was responsibly disclosed and fixed in the upstream library, which also made it into Bitcoin Core 0.12 (released in February 2016).
Large messages from multiple peers can crash nodes : Prior to Bitcoin Core 0.10.1, nodes were limited to a size limit of (approximately) 32MB for P2P messages. And nodes have historically (until now) allowed up to 130 connections by default. If every peer was sending the largest messages at nearly the same time, this would require nodes to allocate 4GB of memory on top of other memory requirements, more than many nodes can afford. This vulnerability was dutifully disclosed by user Evil-Knievel on the BitcoinTalk.org forums, assigned CVE-2015-3641 , and fixed in Bitcoin Core 0.10.1 by limiting message sizes to less than 2MB (later increased to ~4MB for the SegWit upgrade).