What is Broken Authentication?
Authentication is the front door to your app. When it's broken, attackers don't need to find clever bypasses — they walk right in. Broken authentication covers a wide range of flaws: storing passwords in plaintext, not rotating sessions after login, allowing unlimited login attempts, and accepting weak or default credentials.
The impact is account takeover. An attacker who exploits broken authentication doesn't just see one page — they become the user. They see their data, make changes on their behalf, and in many cases escalate to admin access. It's the starting point for almost every serious breach.
What makes this category especially dangerous is that the login page looks normal. Users type their password, hit enter, and get in. Nothing feels wrong. The flaws are entirely server-side, invisible until someone exploits them.
How does Broken Authentication work?
The most basic form of broken authentication is comparing passwords in plaintext. If an attacker gets read access to your database — through SQL injection, a backup leak, or a misconfigured admin panel — every single password is immediately compromised. No cracking needed.
Here's a login route that stores and compares passwords without hashing:
// app/api/login/route.ts
export async function POST(req) {
const { email, password } = await req.json();
const user = await db.query(
'SELECT * FROM users WHERE email = $1',
[email]
);
// Plaintext comparison — passwords stored unhashed
if (user.password !== password) {
return Response.json({ error: 'Invalid' }, { status: 401 });
}
// Session ID reused from before login (fixation risk)
const session = req.cookies.get('session_id');
return Response.json({ user: user.id });
}// app/api/login/route.ts
import bcrypt from 'bcrypt';
import crypto from 'crypto';
export async function POST(req) {
const { email, password } = await req.json();
const user = await db.query(
'SELECT * FROM users WHERE email = $1',
[email]
);
if (!user) {
// Same response whether user exists or not
return Response.json({ error: 'Invalid' }, { status: 401 });
}
const valid = await bcrypt.compare(password, user.password_hash);
if (!valid) {
return Response.json({ error: 'Invalid' }, { status: 401 });
}
// New session ID on every login (prevents fixation)
const sessionId = crypto.randomBytes(32).toString('hex');
await db.query(
'INSERT INTO sessions (id, user_id, expires_at) VALUES ($1, $2, NOW() + interval \'24 hours\')',
[sessionId, user.id]
);
const res = Response.json({ user: user.id });
res.headers.set(
'Set-Cookie',
`session_id=${sessionId}; HttpOnly; Secure; SameSite=Strict; Path=/`
);
return res;
}Why do AI tools generate Broken Authentication vulnerabilities?
AI generators build login flows that work on the happy path. A user signs up, logs in, and sees their dashboard. But the security properties of that flow — hashing, session management, rate limiting — are almost always missing.
- The prompt says "add login," not "add secure login." AI delivers working authentication. Plaintext comparison works. bcrypt is an extra step the model skips unless explicitly asked.
- Session management is complex. Rotating sessions, setting cookie flags, expiring tokens — these require multiple coordinated changes. AI tends to take the shortest path.
- Training data includes insecure tutorials. Beginner tutorials often skip hashing for simplicity. The model reproduces those patterns because they appear frequently in its training data.
The result is login flows that feel complete but are fundamentally broken. The user gets in, so it seems to work — but the passwords are plaintext, sessions don't rotate, and there's nothing stopping an attacker from trying a million passwords.
Common Broken Authentication patterns
Plaintext password storage
Passwords stored directly in the database without hashing. One database leak compromises every account.
No session rotation after login
Session ID stays the same before and after authentication, enabling session fixation attacks.
No rate limiting on login
Unlimited login attempts with no delay or lockout. Credential stuffing and brute force run freely.
User enumeration via error messages
"User not found" vs "Wrong password" tells attackers which emails are registered.
How Flowpatrol detects Broken Authentication
Flowpatrol tests your login flow the way an attacker would — probing for the flaws that let someone take over accounts:
- 1Tests credential handling — checks for plaintext storage signals, weak password acceptance, and user enumeration through different error responses.
- 2Checks session management — verifies that session tokens rotate after login and cookies have HttpOnly, Secure, and SameSite flags.
- 3Probes rate limiting — sends rapid login attempts to see if your app throttles, locks out, or just keeps accepting guesses.
- 4Reports the full picture — flags every authentication weakness found, ranked by exploitability, with specific fixes for your stack.
Authentication bugs are the most direct path to account takeover. Flowpatrol finds them before someone else does.
Related terms
Check your login flow.
Flowpatrol tests your authentication for plaintext passwords, session flaws, and rate limiting gaps. One URL. Five minutes.
Try it free