pub struct PairingCodeGuard { /* private fields */ }Expand description
Per-process brute-force guard for the public code-redemption path.
Design (flagged for review): a 6-digit numeric code is only ~1M wide, and
POST /v2/pair { code } is public, so without a guard it is brute-forceable
within a code’s 120s TTL. The guard is a simple bounded failed-attempt
counter with a cooldown:
- Each failed code redemption increments a counter.
- After [
PAIRING_FAILURE_THRESHOLD] (10) failures, a [PAIRING_COOLDOWN] (60s) lockout trips: all further code redemptions are rejected for the duration, AND the caller proactively clears outstanding codes (so a near-miss attacker can’t resume probing the small space). The counter resets when the cooldown elapses, or on any successful redemption.
This is per-PROCESS, not per-IP (the public route sits behind no reverse proxy that reliably carries client IPs in this deployment), so it is a global rate cap on the code path. The root-password path is untouched (its own throttling is tracked separately in #190). Trade-off: a global cooldown means a determined attacker can also deny a legitimate device’s pairing for 60s by burning failures — acceptable for a short, operator-initiated pairing window.
Implementations§
Source§impl PairingCodeGuard
impl PairingCodeGuard
Sourcepub fn in_cooldown(&self) -> bool
pub fn in_cooldown(&self) -> bool
Whether the code-redemption path is currently locked out. Clears an elapsed cooldown (and its failure count) as a side effect.
Sourcepub fn record_failure(&self) -> bool
pub fn record_failure(&self) -> bool
Record a failed redemption. Returns true IFF this failure tripped the
cooldown (so the caller can invalidate outstanding codes).
Sourcepub fn record_success(&self)
pub fn record_success(&self)
Reset the guard after a successful redemption.