Problem
When bitcoind starts and the HTTP IPv4 listen address is occupied by another process, but the IPv6 address is available, the server fails open and generates a cookie file. When bitcoin-cli runs it picks up the cookie file and sends the credentials in plain text to the non-bitcoind process running on the default IPv4 port. An attacker can then use the credentials to commandeer bitcoind over IPv6.
Solution
Safe defaults:
- When running with default settings, require that the IPv4 bind succeeds.
- When
-rpcbindis specified, require that all HTTP listen socket binds succeed (fail closed-behavior).
Node runners who only have IPv6 are now required to override -rpcbind to only specify the working interface if they were not doing so already.
The problem of bitcoin-cli sending the credentials to what could possibly be the wrong process remains only in non-default setups.
History
40b556d3742a1f65d67e2d4c760d0b13fe8be5b7 from 2015 switched the HTTP server from Boost Asio to LibEvent, and binding switched from an attempt at dual-binding IPv4+v6 and falling back to IPv4-only (rpcserver.cpp / StartRPCThreads()), to binding IPv4 or IPv6 (httpserver.cpp / HTTPBindAddresses()). The current PR restores the prior behavior of IPv4 being mandatory.
#14968 from 2018 was an attempt to change the behavior to require all binds to succeed. But it ran into issues with poor IPv6 support on CI.
Severity
This credential exfiltration attack requires capability to launch processes on the bitcoind host. If we are on the same account we can already read the cookie credentials off disk. So it's only really interesting when an attacker is on a different user account on the same host.
Disclaimer
The 2 commits with multiple authors were probably initially generated with the help of silicon LLMs.