#36187 http: Restore requirement of IPv4 bind success

ReviewabilityReviewsAgreementSize
#36187 hodlinator http: Restore requirement of IPv4 bind successReady0Strong57 + 71 tests
  • Prevent local cross-user RPC credential theft when another process occupies the default IPv4 loopback port
  • Require the default IPv4 loopback bind to succeed during startup before writing the RPC cookie
  • Ready for review
  • Broad agreement on requiring an IPv4 listener since bitcoin-cli defaults to IPv4 (winterrdog)
  • Concept approval without extensive rationale (janb84, l0rinc, sedited)
  • Suggestions regarding error messaging and log levels were addressed or deferred without blocking
  • 57 lines added or modified outside tests
  • 71 lines added or modified in tests
  • 14 lines removed in total
  • 3 files, 4 commits
RPC / REST / ZMQ#1 of 55
P1 · bug fix
  • P1 because it resolves a security flaw where bitcoind fails open on partial endpoint binds
  • Prevents rogue local processes on IPv4 from capturing plaintext cookies sent by default CLI tools
Reviewability: ReadyStalePaused
Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets
Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs.
Size: lines added or modified outside tests, then in tests; greener = smaller.

Goal

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.

Reviewability

Ready

Nothing known that would invalidate a review now.

Waiting on (from the thread read):

  • reviewer: re-review from winterrdog following the pushed commit 2026-09-11
  • reviewer: review of latest push 2026-09-11

Agreement

Strong

substantive support, no open objection (winterrdog)

Thread notes: Reclassified winterrdog's error message comment from objection to suggestion and updated status to fixed following the author's push; added janb84's suggestion on log levels; updated stances and support records. / Re-classified winterrdog's error message comment as a suggestion and marked it fixed after the author pushed changes. Added janb84's suggestion on logging level. Updated winterrdog's stance to support.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
janb84 (member)suggestion, maintenancelog required RPC endpoint binding failures with LogError instead of LogWarning since they abort startupanswered · author deferred pending agreement from other reviewersansweredyes2026-09-08: 'Currently even the required entry/bindings failure only logs as a LogWarning. Is that the correct level for something that aborts startup ?'
Status from: 2026-09-08: hodlinator: 'Will do if others agree, holding off for now.'
winterrdog (contributor)suggestion, interfacemake the error message more actionable for IPv6-only hosts by pointing users to -rpcbindfixed · fix pushed · author pushed a commit addressing winterrdog's review feedbackansweredyes2026-09-10: 'can we make the IPv6-only case a bit more actionable in the error message ?'
Status from: 2026-09-11: hodlinator: 'addresses points from https://github.com/bitcoin/bitcoin/pull/36187#pullrequestreview-5172841125.'

Support:

  • l0rinc (member) (Concept ACK, 2026-09-07): thanks for pushing the fix [not substantive]
  • janb84 (member) (Concept ACK, 2026-09-08) [read]: Looks good, some suggestion NITS. [not substantive]
  • sedited (member) (Concept ACK, 2026-09-09): (no reason given) [not substantive]
  • winterrdog (contributor) (Concept ACK, 2026-09-10) [read]: this makes sense since `bitcoin-cli` defaults to IPv4, so `bitcoind` should have a corresponding IPv4 listener, already working by default as well

Participants:

  • l0rinc (member, support, 1 statements 2026-09-07 to 2026-09-07): Concept ACK
  • janb84 (member, support, 4 statements 2026-09-08 to 2026-09-08): Concept ACK with comments on logging and style
  • sedited (member, support, 1 statements 2026-09-09 to 2026-09-09): Concept ACK
  • winterrdog (contributor, support, 3 statements 2026-09-10 to 2026-09-10): Concept ACK; suggested more actionable error message for IPv6-only hosts

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

The short text the ranking pass compares across PRs.

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.

Data

dossier JSON · extract JSON · model ledger, generated 2026-09-26T01:24, confidence high, input hash 832eee69462a5e43
thread read through 2026-09-21 (15 statements), head 05de7be9d7
labels: RPC/REST/ZMQ

Categories

RPC / REST / ZMQ

P1 · bug fix

Fixes a local credential theft vulnerability where bitcoind fails open on partial binds. When IPv4 is occupied by a rogue local process but IPv6 binds, bitcoind writes out an RPC cookie that bitcoin-cli subsequently sends in plaintext to the rogue process by default.

Membership: Matches the RPC/REST/ZMQ label and modifies HTTP server bind initialization and credential exposure in src/httpserver.cpp.

Factors: security/stability 2, bug 2, performance 0, user value 1, leverage 0