M6 hardening: /recheck binds 0.0.0.0 (unauthenticated re-run trigger) #8
Labels
No labels
correctness
coverage
milestone:M4
polish
security
tech-debt
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
public/warden#8
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
M5 whole-branch review (v0.17.0) minor, non-blocking hardening finding.
roles.run_roleserves the new nodePOST /recheckonsettings.http_bind, which defaults to0.0.0.0(config.py:176)./recheckis an unauthenticated POST that forces the node to re-run and re-publish its own checks. On an untrusted/reachable network this is a mild bus/CPU amplification (DoS) vector.Fail-closed is intact: an attacker cannot fake an OK (the detector runs for real), so this cannot cause a false resolution. It is consistent with the current mesh trust posture (
/healthalready binds 0.0.0.0; NATS auth/TLS explicitly deferred to M6). The orchestrator-driven path is loopback (the warden.caps.recheck helper POSTs to 127.0.0.1).Fix (M6): bind /recheck to loopback (or gate it), and reconcile the doc/impl asymmetry: the caps-helper docstring says the client is 'always loopback' while the server binds broadly.
Found by the M5 whole-branch review; deferred as non-blocking.
Fixed in v0.18.0 (commits
66d6d81+23e50d6).POST /recheckis now gated to loopback callers (403 off-box, nothing published/run), reading the real TCP peer (self.client_address, not a spoofable header); /health unchanged. The caps-helper docstring is reconciled. Follow-up fix23e50d6makes IPv4-mapped loopback (::ffff:127.0.0.1) recognition correct on Python >=3.10 (not just 3.13+).