← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Brute Force Attack

Security CWE-307 OWASP A7:2021 CVSS 7.5 PHP 5.0+ Beginner
debt(d7/e5/b5/t7)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The detection_hints specify semgrep with automated:no, and the code_pattern is 'Login handler with no failed-attempt counter or lockout mechanism' — this is an absence-of-control pattern that requires deliberate manual inspection or a custom semgrep rule to catch; it won't surface from a default linter scan.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix requires adding rate limiting, account lockout, CAPTCHA, and switching to bcrypt/Argon2 — this touches the login handler, password reset endpoint, OTP endpoints, and the password hashing layer, spanning multiple files and components rather than a single-line patch.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). The applies_to contexts are web and api, meaning every authentication-related endpoint carries this concern. Tags include rate-limiting and owasp-top10, indicating it shapes how login, reset, and OTP flows must be designed and reviewed going forward, but it doesn't define the entire system shape.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap (contradicts how a similar concept works elsewhere)' (t7). The misconception field states explicitly: 'Locking an account after 5 attempts fully prevents brute force.' This is a well-known, widely-deployed defence that developers confidently apply yet it introduces denial-of-service risk and is bypassed by distributed low-and-slow attacks — a serious trap because the 'obvious' countermeasure is both incomplete and harmful.

About DEBT scoring →

Also Known As

password guessing credential brute force

TL;DR

Systematically trying every possible password or key until the correct one is found.

Explanation

A brute force attack tries all possible combinations of characters until the correct password, token, or encryption key is found. Against a fast hash like MD5, an attacker can test billions of guesses per second on commodity hardware. Defences include: slow hashing algorithms (bcrypt, Argon2), account lockout or progressive delays after failed attempts, CAPTCHA for login forms, and multi-factor authentication. Rate limiting at the application and infrastructure level adds another layer.

Diagram

flowchart TD
    ATK[Attacker tries passwords] --> RATE{Rate limit check}
    RATE -->|under limit| TRY[Attempt login]
    RATE -->|over limit| LOCK[429 Too Many Requests<br/>Retry-After header]
    TRY -->|failed| COUNT[Increment failure counter]
    COUNT --> THRESH{Threshold reached?}
    THRESH -->|yes| LOCKOUT[Account lockout<br/>5 min exponential backoff]
    THRESH -->|no| RATE
    subgraph Defences
        BCRYPT2[bcrypt Argon2 - slow hashing<br/>1000 attempts/s not billions]
        NOTIFY2[Email user on lockout]
        GEO[Block unusual geography]
    end
style LOCK fill:#f85149,color:#fff
style LOCKOUT fill:#f85149,color:#fff
style BCRYPT2 fill:#238636,color:#fff

Common Misconception

Locking an account after 5 attempts fully prevents brute force. Lockout causes denial-of-service against legitimate users and is bypassed by low-and-slow attacks spread across many IPs.

Why It Matters

Without rate limiting or lockout, an attacker can submit millions of password guesses against a login endpoint — a leaked hash database makes offline brute force even faster.

Common Mistakes

  • No rate limiting or account lockout on login, password reset, or OTP endpoints.
  • Lockout based on username only — attackers distribute attempts across many accounts to avoid per-account limits.
  • Using weak password hashing (MD5, SHA1) that makes offline cracking trivial after a database breach.
  • CAPTCHA as the only defence — solvable by third-party services; rate limiting is also needed.

Code Examples

✗ Vulnerable
// No rate limiting — unlimited password guesses:
if ($_POST['password'] === $user['password_hash']) {
    // login success
}
✓ Fixed
// Rate limit login attempts per IP and per account
class LoginController {
    public function login(Request $req): Response {
        $key = 'login_attempts:' . $req->ip() . ':' . $req->input('email');

        if ($this->cache->get($key, 0) >= 5) {
            return response()->json(['error' => 'Too many attempts'], 429);
        }

        if (!$this->auth->attempt($req->only('email', 'password'))) {
            $this->cache->increment($key);
            $this->cache->expire($key, 900); // 15-minute window
            return response()->json(['error' => 'Invalid credentials'], 401);
        }

        $this->cache->delete($key);
        return response()->json(['token' => $this->auth->token()]);
    }
}

Added 15 Mar 2026
Edited 22 Mar 2026
Views 67
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 2 pings S 4 pings S 3 pings M 2 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 1 ping W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Scrapy 12 Perplexity 10 Amazonbot 10 Ahrefs 5 SEMrush 4 Google 4 Bing 3 Unknown AI 2 Claude 2 ChatGPT 2 Qwen 1 PetalBot 1
crawler 52 crawler_json 4
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Add rate limiting + account lockout after N failed attempts + CAPTCHA on login; use bcrypt/Argon2 to make each guess expensive
📦 Applies To
PHP 5.0+ web api
🔗 Prerequisites
🔍 Detection Hints
Login handler with no failed-attempt counter or lockout mechanism
Auto-detectable: ✗ No semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: File Tests: Update
CWE-307 CWE-308


✓ schema.org compliant