Stop 05 · Vulnerabilities & OWASP Top 10Topics · 5/11

Broken Authentication

Part of the Cybersecurity Roadmap

In short

If your login lets someone try a million passwords, accepts "123456", or keeps sessions alive forever, the strongest firewall won't save you. Login is the front door; build it properly.

Weaknesses in login mechanisms — weak password policies, exposed session tokens, missing rate limiting on login attempts — that let attackers bypass or hijack authentication entirely.

The blob looks worried as a hooded figure tries keys from a big key ring in a wooden door's lock.

Think of it like this

The stranger with a huge key ring

A stranger stands at your flat door with a ring of 200 keys, trying them one by one. A door that allows endless tries will open eventually. A good lock jams after five wrong keys, and the society guard gets a call.

Watch it happen

The layers a login request should pass

Login form
Rate limit
Hash check
MFA
New session

1/5A login arrives with an email and password over HTTPS.

The big ideas

What you need to know

Slow down guessing

Rate limits, gradual delays and CAPTCHA after repeated failures make password guessing too slow to be worth it.

MFA stops reused passwords

People reuse passwords across sites. A second factor means a leaked password alone isn't enough.

Vague error messages

Say "wrong email or password", not "no such user". Specific messages help outsiders find valid accounts.

Sessions that end

New session ID after login, expiry after idle time, and a logout that really destroys the session on the server.

See it in code

Walk through the code

ts
1import rateLimit from "express-rate-limit";2import bcrypt from "bcrypt";3 4const loginLimiter = rateLimit({ windowMs: 15 * 60 * 1000, limit: 5 });5 6app.post("/login", loginLimiter, async (req, res) => {7  const user = await db.user.findUnique({ where: { email: req.body.email } });8  const ok = user && (await bcrypt.compare(req.body.password, user.passwordHash));9  if (!ok) return res.status(401).json({ error: "Wrong email or password" });10  req.session.regenerate(() => {11    req.session.userId = user.id;12    res.json({ ok: true });13  });14});

1/4Five attempts per 15 minutes per client. Extra tries get 429 before touching the database.

Real apps also lock or slow down per account, not just per IP, and log repeated failures so someone can spot an attack.

Save yourself the pain

Common mistakes

Oops

Forcing complex password rules but allowing "Password@123".

Do this instead

Prefer long passphrases and block known-breached passwords, as NIST guidance suggests, instead of odd symbol rules.

Oops

Putting session tokens in URLs like /dashboard?session=abc.

Do this instead

URLs end up in logs, history and Referer headers. Keep tokens in HttpOnly, Secure cookies.

Your mission

Harden a login you wrote

~40 min

Quick check

Your login says "No account with this email" for unknown users. Why is that a problem?

Go deeper

  1. 1Test a practice app's login for weak password requirements or missing rate limiting.
  2. 2Learn why session tokens should be regenerated after login (preventing session fixation).
  3. 3Understand credential stuffing as a common real-world exploitation of broken authentication.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge