Weakness reference
CWE-521

Weak Password Requirements

This weakness occurs when a system allows users to set passwords that are too simple, short, or predictable — making accounts vulnerable to guessing and…

01Summary

This weakness occurs when a system allows users to set passwords that are too simple, short, or predictable — making accounts vulnerable to guessing and brute-force attacks. Strong password requirements are a foundational defense; without them, even well-protected backends can be compromised through weak credentials alone.

02How It Happens

Password strength is typically enforced at account creation or password-change time. When a system either does not validate password complexity at all, or enforces only minimal rules (e.g., "at least 1 character"), attackers can register accounts or reset passwords to trivial values like 123456, password, or a username. Automated tools can then rapidly test these weak credentials against login endpoints. The weakness is compounded if the system also lacks rate-limiting on login attempts or does not enforce account lockout after repeated failures.

03Real-World Impact

Weak password requirements directly enable account takeover. An attacker can guess or brute-force credentials to gain unauthorized access to user accounts, administrative panels, or shared systems. Once inside, they may steal data, modify content, plant malware, or pivot to other systems. Organizations with weak password policies often experience higher rates of credential-based breaches and are more vulnerable to insider threats.

04Vulnerable & Fixed Patterns

Vulnerable pattern
def create_account(username, password):
    # No password strength validation
    if len(password) > 0:  # Only checks that password is not empty
        user = User(username=username, password=password)
        user.save()
        return "Account created"
    return "Password required"

Why it's vulnerable:
The code accepts any non-empty password, including single characters, common words, or sequences like 123. An attacker can set a password like a and later brute-force it trivially.

Fixed pattern
import re

def create_account(username, password):
    # Enforce minimum length and complexity
    if len(password) < 12:
        return "Password must be at least 12 characters"
    if not re.search(r'[A-Z]', password):
        return "Password must contain an uppercase letter"
    if not re.search(r'[a-z]', password):
        return "Password must contain a lowercase letter"
    if not re.search(r'[0-9]', password):
        return "Password must contain a digit"
    if not re.search(r'[!@#$%^&*]', password):
        return "Password must contain a special character"
    
    user = User(username=username, password=password)
    user.save()
    return "Account created"
Vulnerable pattern
<?php
function create_account($username, $password) {
    // No password strength validation
    if (!empty($password)) {
        $user = new User($username, $password);
        $user->save();
        return "Account created";
    }
    return "Password required";
}
?>

Why it's vulnerable:
The function only checks that the password is not empty. Users can set passwords like 1, test, or abc, all of which are trivial to guess or brute-force.

Fixed pattern
<?php
function create_account($username, $password) {
    // Enforce minimum length and complexity
    if (strlen($password) < 12) {
        return "Password must be at least 12 characters";
    }
    if (!preg_match('/[A-Z]/', $password)) {
        return "Password must contain an uppercase letter";
    }
    if (!preg_match('/[a-z]/', $password)) {
        return "Password must contain a lowercase letter";
    }
    if (!preg_match('/[0-9]/', $password)) {
        return "Password must contain a digit";
    }
    if (!preg_match('/[!@#$%^&*]/', $password)) {
        return "Password must contain a special character";
    }
    
    $user = new User($username, $password);
    $user->save();
    return "Account created";
}
?>

05Prevention Checklist

Enforce a minimum password length of at least 12 characters; 16+ is recommended for high-value accounts.
Require at least three of four character classes: uppercase letters, lowercase letters, digits, and special characters.
Reject passwords that match the username, common dictionary words, or previously breached password lists (use a service like Have I Been Pwned API or a local dictionary).
Implement account lockout after 5–10 failed login attempts within a short window (e.g., 15 minutes), and require manual unlock or a time delay.
Display password strength feedback in real time during account creation and password changes to guide users toward stronger choices.
Consider requiring multi-factor authentication (MFA) as a compensating control, especially for administrative or sensitive accounts.

06Signs You May Already Be Affected

Check your user database or account logs for patterns of weak passwords: very short passwords (under 8 characters), passwords matching usernames, or passwords composed only of digits or lowercase letters. If your login logs show repeated failed attempts from the same IP address followed by a successful login, or if you find unexpected admin accounts with simple credentials, your system may have been compromised via weak password guessing.

07Related Recent Vulnerabilities