fix(security): admin auth on block-slot, block-producers, and wallet endpoints#6715
fix(security): admin auth on block-slot, block-producers, and wallet endpoints#6715BossChaos wants to merge 1 commit into
Conversation
Vulnerabilities fixed: - /block/slot: Exposed internal slot scheduling, balance summary, producer turn timing — attackers can infer mining schedule - /block/producers: Exposed miner wallet addresses, selection weights, device arch — enables targeted attacks on producers - /api/wallet/<wallet>: Exposed any wallet balance, enrollment weight, tier classification, network age — full account intelligence leak All three endpoints now require X-Admin-Key header matching RC_ADMIN_KEY env var, consistent with the auth pattern used in other RustChain modules. Fix: add _require_admin() guard to list_producers(), get_current_slot(), and api_wallet_lookup().
zqleslie
left a comment
There was a problem hiding this comment.
Reviewed the security hardening PR adding admin auth to three information-disclosure endpoints.
Scope reviewed:
node/rustchain_block_producer.py:_get_admin_key()+_require_admin()guard added toget_current_slot()andlist_producers()node/rustchain_dashboard.py: Duplicate_require_admin()guard added toapi_wallet_lookup()
Assessment:
-
Correctness: The
_require_admin()pattern is identical to what's already deployed inrustchain_v2_integrated_v2.2.1_rip200.pyfor/withdraw/request,/governance/propose, and/governance/vote. This is consistent and low-risk. -
Fail-safe: When
RC_ADMIN_KEYis unset, returns 503 rather than allowing unauthenticated access. Good. -
Endpoint impact:
GET /block/slot— exposes slot scheduling + balance summary → reasonable to protectGET /block/producers— exposes miner addresses + weights → reasonable to protectGET /api/wallet/<addr>— exposes any wallet balance → high value to protect, this is the most critical of the three
-
Minor note:
_require_admin()is duplicated acrossrustchain_block_producer.pyandrustchain_dashboard.py. Not a blocker for this PR, but worth consolidating into a shared module in a follow-up.
No blockers. If accepted, routing via bounty #73.
This is a review claim for maintainer assessment only.
zqleslie
left a comment
There was a problem hiding this comment.
Reviewed the security hardening PR adding admin auth to 3 endpoints across 2 files.
Endpoints secured:
GET /block/slot→ slot scheduling + balance summary (medium sensitivity)GET /block/producers→ miner addresses, weights, device arch (medium sensitivity)GET /api/wallet/<addr>→ any wallet balance, enrollment weight, tier (high sensitivity)
Assessment:
-
_require_admin()pattern is consistent — matches the existing auth guard inrustchain_v2_integrated_v2.2.1_rip200.pyfor/withdraw/requestand governance endpoints. Useshmac.compare_digest()for timing-safe comparison. Returns 503 whenRC_ADMIN_KEYis unset, which fails closed correctly. -
rustchain_block_producer.py: The_get_admin_key()and_require_admin()helpers are defined insidecreate_block_api_routes(), giving them access to Flask'srequestcontext via closure. This works correctly since Flask sets uprequestper-request in the same thread. -
rustchain_dashboard.py: Same pattern, standalone functions using Flask'srequestglobal.api_wallet_lookupis the most critical endpoint here — exposing arbitrary wallet balances without auth is a real information-leak risk. The503fallback whenRC_ADMIN_KEYisn't set is correct (better than 401, signals misconfiguration not bad credentials). -
No blockers found — this is a clean, narrowly-scoped security fix. No runtime behavior changes beyond auth gating.
Review claim: bounty #73
MolhamHamwi
left a comment
There was a problem hiding this comment.
I reviewed node/rustchain_block_producer.py and node/rustchain_dashboard.py in this PR.
Two technical observations:
-
The fail-closed behavior is sound:
_require_admin()returns503whenRC_ADMIN_KEYis unset, so these newly protected endpoints do not accidentally remain public in a misconfigured deployment. Usinghmac.compare_digest()for the providedX-Admin-Keyalso matches the existing constant-time comparison pattern used elsewhere in the project. -
The route coverage looks consistent with the stated data-exposure scope: both
/block/slotand/block/producersare guarded insidecreate_block_api_routes(), and/api/wallet/<wallet_address>is guarded before opening the SQLite connection, so unauthenticated callers are rejected before wallet/producer details are read. One small cleanup I noticed:hashlibis imported inrustchain_block_producer.pybut does not appear to be used by this patch.
I received RTC compensation for this review.
|
Holding for a maintainer call — the auth helper is well-built (constant-time, fail-closed 503-on-unset), but this gates read-only GET endpoints |
…ucers (#6755) Per Scott's call, /block/slot, /block/producers, and /api/wallet stay PUBLIC (proof-of-antiquity consensus transparency the explorer/dashboard depend on; no secrets/IPs/keys are exposed). The only hardening kept after tri-brain review: expose device_info through an explicit field allowlist (arch/family/model/year/enroll_weight) so a future column added to device_info (e.g. an IP/hostname) can never leak through this unauthenticated endpoint. Output is unchanged for current data; a non-dict/None row degrades to {} instead of raising. is_my_turn and the balance summary are intentionally left as-is to avoid breaking the public API contract. Supersedes #6715 (which admin-gated these public endpoints and would have broken the explorer). Tri-brain reviewed (Codex/Grok; GPT-OSS offline) — earlier over-broad changes (removing is_my_turn, capping balance) were reverted as regressions. Co-authored-by: Scott Boudreaux <scottbphone12@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Closing in favor of keeping these endpoints PUBLIC. |
Summary
Three unauthenticated endpoints exposed sensitive internal data:
GET /block/slotGET /block/producersGET /api/wallet/<wallet>Fix
Added
_require_admin()guard (X-Admin-Key header vs RC_ADMIN_KEY env var) to:list_producers()get_current_slot()api_wallet_lookup()Consistent with the auth pattern used throughout the RustChain codebase (bcos_routes.py, sophia_governor.py, etc.).
Files
node/rustchain_block_producer.py: Addedimport hmac,_get_admin_key(),_require_admin(), auth on 2 endpointsnode/rustchain_dashboard.py: Addedimport hmac,_get_admin_key(),_require_admin(), auth on 1 endpoint