Missing Rate Limiting (Brute-Force)
Login and form endpoints accept unlimited attempts, letting attackers brute-force passwords at full speed.
What is Missing Rate Limiting (Brute-Force)?
When a login form, password-reset endpoint, or API route accepts unlimited requests, attackers can test passwords (or stolen credential pairs) as fast as the server and network allow. The dominant attack is credential stuffing: bots replay username/password pairs from unrelated breaches against your login, because passwords are reused. Without throttling there is nothing that slows them down — a single machine can test hundreds of thousands of combinations per day against one form. Rate limiting (progressive delays, request quotas per IP and per account, lockouts, and CAPTCHA escalation) turns that firehose into a trickle and makes attacks uneconomical.
Why It Matters to Your Business
Missing rate limiting converts password reuse into account takeover at industrial scale. Beyond account breaches, unthrottled endpoints are abused for resource exhaustion (cheap DoS), SMS/email bombing of reset endpoints (costing you per message and harassing your users), and scraping. It is an OWASP Top 10 category (A07) finding that appears in every security review, and fixing it is a few lines of middleware.
How to Fix It
Laravel (throttle middleware — per-IP by default):
Route::post('/login', [AuthController::class, 'login'])
->middleware('throttle:5,1'); // 5 attempts per minute per IP
// For login specifically, rate-limit per ACCOUNT too (defends distributed attacks):
RateLimiter::for('login', function (Request $r) {
return Limit::perMinute(5)->by($r->input('email').'|'.$r->ip());
});
Nginx (generic request quota):
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
location = /login { limit_req zone=login burst=3 nodelay; }
Express: express-rate-limit. Django: django-ratelimit or DRF throttle classes.
Escalate in layers: throttle -> CAPTCHA after N failures -> temporary lockout -> alert. Add MFA and the stolen-password problem largely disappears regardless of attempt speed.
Frequently Asked Questions
How many login attempts should I allow?
A practical baseline: 5 attempts per minute per IP, plus a per-account counter (e.g. 10 failures triggers a 15-minute cooldown or CAPTCHA). Humans rarely trip this; bots constantly do. Always pair per-IP and per-account limits — either alone is bypassable.
Is a CAPTCHA enough instead of rate limiting?
No — modern CAPTCHA solvers are cheap and automated. Use CAPTCHA as an escalation layer after throttling triggers, not as the primary control. Throttling cannot be solved; it can only be distributed.
Does Cloudflare already rate-limit my site?
Partially — Cloudflare's free WAF and bot tools blunt large floods, but per-account logic and application-aware limits still belong in your app. Distributed, low-and-slow attacks walk right through generic network-level rules.
Technical Classification
| OWASP Category | A07:2021 — Identification and Authentication Failures |
| CWE ID | CWE-307: Improper Limitation of the Number of Login Attempts |
| Detected By | rate_limit scanner(s) |
| Severity Level | medium |
How 2MNY Security Can Help
Check if your website has this vulnerability
Our rate_limit scanner checks for this issue automatically.
Scan My Website FreeRelated Vulnerabilities
Open Redirect Vulnerability
The site has an open redirect — a parameter that redirects to any URL, allowing phishing campaigns that appear to come from your domain.
Dangerous HTTP Methods Enabled
The server allows dangerous HTTP methods (PUT, DELETE, TRACE, CONNECT, WebDAV) that can be abused for file upload, deletion, or cross-site tracing.
SQL Injection (Reflected) Vulnerability
Unvalidated user input flows into database queries, letting attackers read your data or take over the server.
Reflected Cross-Site Scripting (XSS)
User input is echoed into pages unescaped, so crafted links run attacker JavaScript in your visitors' browsers.