Disclosure of censorship due to transaction re-request handling



An attacker could prevent a node from seeing a specific unconfirmed transaction.

This issue is considered Medium severity.

Details

Before this issue was fixed in PR 19988, the “g_already_asked_for” mechanism was used to schedule GETDATA requests for transactions. The SendMessages() function would send out GETDATAs for transactions recently announced by peers, remembering when that request was sent out in g_already_asked_for. However, this g_already_asked_for was a “limitedmap” data structure, with a bounded size that would forget the oldest entries if it reaches 50000 entries. This makes the following attack possible:

The attacker is the first to announce a legitimate transaction T to the victim.
The victim requests T from the attacker using GETDATA.
The attacker does not respond to GETDATA until close to the time when the victim would request T from other peers (~60 seconds).
Then, the attacker carefully spams the victim with bogus announcements, causing the victim’s g_already_asked_for to evict T.
The attacker announces T again to the victim (due to how the queueing works in m_tx_process_time, this does not need to be timed particularly accurately).
The victim, not finding T in g_already_asked_for will treat it as a new announcement, sending a new GETDATA for it to the attacker.
The attacker again does not respond to GETDATA.
etc.

This way, the attacker can prevent the victim from ever requesting the transaction from anyone but the attacker.

Attribution

Responsibly disclosed by John Newbery, claiming discovery by Amiti Uttarwar and him.

Timeline

2020-04-03 John Newbery reports the bug in an email to Suhas Daftuar and others
2020-05-08 John Newbery suggests an approach to fixing the bug
2020-09-21 Pieter Wuille opens PR #19988 as a comprehensive approach to fixing this and other bugs
2020-10-14 Pieter’s PR is merged
2021-01-14 Bitcoin Core version 0.21.0 is released with a fix
2022-04-25 The last vulnerable Bitcoin Core version (0.20.x) goes EOL
2024-07-03 Public disclosure