C.W.K.
Stream
Lesson 02 of 05 · published

The Lockout Cycle — Counter, Threshold, Blacklist

~15 min · lockout, state-machine, rate-limit

Level 0Greenhorn
0 XP0/53 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

A clean three-state machine: fresh, warned, locked. Each PIN attempt advances the state for that source IP.

StateCounter rangeWhat happens on next attempt
Freshfail_count = 0Verify PIN; on fail → increment to 1
Warned1 ≤ fail_count < max_retryVerify PIN; on fail → increment; on success → reset to 0
Lockedfail_count ≥ max_retryReject before bcrypt; add IP to blacklist; admin must release

The "reset on success" trade

Resetting the counter on a successful login is friendly: a few legitimate typos before getting it right do not lock you out. It is also safe: the attacker doesn't know the PIN, so they can't reset the counter by guessing right — they'd have to guess right to do that, in which case the auth has already succeeded and they don't need to brute force anymore.

Code

The annotated lockout cycle inside POST /login·python
# Inside POST /login (full version in Track 5)

# Already locked? Don't even verify — saves bcrypt cost.
if attempt_count(ip) >= MAX_RETRY:
    blacklist(ip, "exceeded_retry")
    return Response("Locked out", status_code=429)

# Verify
if not verify_pin(input_pin, stored_hash):
    increment_attempt(ip)               # bump counter
    await asyncio.sleep(0.5)            # constant time
    return Response("Invalid PIN", status_code=401)

# Success
clear_attempts(ip)                      # reset counter
issue_session(ip)

External links

Exercise

Stress-test your /login endpoint: write a small script that POSTs a wrong PIN 10 times. After attempt 5, you should see the IP appear in security_blacklist with reason='exceeded_retry'. After attempt 6, you should see HTTP 429. Verify the database reflects the state machine.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.