#36187 http: Require default IPv4 bind to succeed (again)
https://github.com/bitcoin/bitcoin/pull/36187 · · +128/-14 in 3 files, 4 commits · labels: RPC/REST/ZMQ
Goal
- Prevent local credential theft when another process occupies the default IPv4 RPC port
- Require the default IPv4 loopback bind to succeed during startup instead of failing open
- Ensure explicit bind configurations fail closed if any specified endpoint cannot be bound
This PR modifies HTTP server initialization in `src/httpserver.cpp` so that the default IPv4 loopback bind (127.0.0.1) is required to succeed during startup, while the default IPv6 loopback bind (::1) remains optional. It also changes explicit `-rpcbind` configurations to fail closed if any specified endpoint cannot be bound, and adds functional tests covering partial binds and credential safety.
Problem: When the default IPv4 RPC port is occupied by another local process, bitcoind currently fails open if IPv6 binds successfully, writing out an RPC cookie. When `bitcoin-cli` runs, it sends plain-text cookie credentials to the rogue IPv4 process by default, enabling local cross-user credential theft.
Category: RPC / REST / ZMQ (#1 of 52)
P2 · bug fix
- P2 because it fixes a local credential exfiltration risk on multi-user systems
- P2 because interface security and credential exposure are top priorities for RPC defaults
Prevents local authentication credential exfiltration caused by partial bind failures on multi-user systems. In the RPC category, interface security and credential exposure are top priorities, making this fail-closed behavior a strategically important improvement to default node safety.
Membership: Modifies HTTP server bind setup in src/httpserver.cpp and adds test coverage in test/functional/rpc_bind.py.
Factors: security/stability 2, bug 2, performance 0, user value 1, leverage 0
Reviewability: Ready
- Ready for review
- Code and functional tests are complete with green CI and feedback addressed
The code and functional tests are complete, CI is green, and all reviewer feedback on style and error messaging has been addressed.
Author status: active
Resolved concerns:
- Logging level and style consistency for required versus optional bind failures (raised by janb84, resolved by author)
- Clearer error messaging pointing IPv6-only node operators to explicit `-rpcbind` usage (raised by winterrdog, resolved by author)
Agreement: Strong
- Strong support for failing closed to avoid exposing credentials to rogue local processes
- Matches the CLI default IPv4 target to a mandatory bitcoind listener (winterrdog)
- Concept approval without detailed objections (l0rinc, janb84, sedited, winterrdog)
Strong support; reviewers affirmed the necessity of fail-closed binds to protect cookie credentials.
Four contributors provided Concept ACKs noting that matching the CLI default target to a mandatory bitcoind listener fixes a genuine credential exposure hazard, with all review feedback already applied.
- winterrdog noted: 'this makes sense since bitcoin-cli defaults to IPv4, so bitcoind should have a corresponding IPv4 listener, already working by default as well'
- Concept ACKs from l0rinc, janb84, sedited, winterrdog
Review verdicts (DrahtBot): 0
- Concept ACK: l0rinc, janb84, sedited, winterrdog
Files
74 lines under test/bench/ci.
- test/functional/rpc_bind.py +71/-2
- src/httpserver.cpp +57/-11
- test/functional/feature_config_args.py +0/-1
Card
This PR alters the HTTP server initialization to require that the default IPv4 loopback bind succeeds, avoiding partial startup when only IPv6 succeeds. Currently, an unprivileged local process occupying the IPv4 RPC port can receive plain-text auth cookie credentials when bitcoin-cli connects, while bitcoind runs on IPv6. Explicit `-rpcbind` invocations are also made fail-closed across all endpoints. Reviewers strongly support the approach and all open feedback has been resolved.