Skip to content

Fix Lack of Rate Limiting on login (API4:2019, Challenge 8) - #73

Closed
beanbeah wants to merge 1 commit into
OWASP-CTF:dc34-ctffrom
beanbeah:ctf/r2-challenge-8-lack-of-rate-limiting-login
Closed

beanbeah wants to merge 1 commit into
OWASP-CTF:dc34-ctffrom
beanbeah:ctf/r2-challenge-8-lack-of-rate-limiting-login

Conversation

@beanbeah

@beanbeah beanbeah commented Aug 9, 2026

Copy link
Copy Markdown

Vulnerability

POST /users/v1/login had no throttling, lockout, or backoff of any kind, so credentials could be brute-forced with unlimited attempts (API4:2019 Lack of Resources & Rate Limiting).

Fix

Added an in-memory login lockout in api_views/users.py, keyed by client IP + the attempted username:

  • After 5 failed login attempts within a 60 second window, further attempts for that key (even with the correct password) receive 429 Too Many Requests with a Retry-After header until the window expires.
  • A successful login clears the failed-attempt counter for that key.
  • Unrelated accounts / source IPs are unaffected — lockout is scoped per (ip, username).

No new third-party dependency required.

Testing (local, WSL)

  • Ran the app locally (vulnerable=1), seeded via /createdb.
  • Sent 5 wrong-password attempts against name1 -> all 200 with the existing bad-password message.
  • 6th attempt -> 429 lockout message, confirming the brute-force is now throttled.
  • Sent the correct password for name1 while still inside the lockout window -> still 429, confirming lockout can't be bypassed by eventually guessing right.
  • Logged in as a different user (name2) during name1's lockout -> succeeded normally (200 + auth token), confirming unrelated accounts aren't affected.
  • Waited for the 60s window to expire, then retried name1 with the correct password -> succeeded normally (200 + auth token), confirming legitimate login still works once the lockout clears.

🤖 Generated with Claude Code

POST /users/v1/login had no throttling, lockout, or backoff, allowing
unlimited credential brute-forcing. Adds an in-memory lockout keyed by
client IP + attempted username: after 5 failed attempts within a 60s
window, further attempts (including with the correct password) get a
429 with Retry-After until the window expires. Successful login clears
the counter for that key; unrelated accounts/IPs are unaffected.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown

🏆 VAmPI — CTF Patch Score

░░░░░░░░░░░░░░░░░░░░  0 / 16 pts  (0%)

0 / 9 challenges patched

Per-challenge detail is withheld — it would reveal the rubric.

Commit: 3eb0ee6 · scoring run

No points yet — this commit didn't solve any challenges, so there's nothing on the leaderboard for it. Patch a vulnerability and push again! 💪

@beanbeah

beanbeah commented Aug 9, 2026

Copy link
Copy Markdown
Author

Superseded by consolidated PR #74 (#74), which merges all validated challenge fixes into one branch. Closing this individual PR.

@beanbeah beanbeah closed this Aug 9, 2026
@beanbeah
beanbeah deleted the ctf/r2-challenge-8-lack-of-rate-limiting-login branch August 9, 2026 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants