पाठ 5 / 25

Designing the Login Flow

Generic errors, throttling and lockout trade-offs.

What a careful login endpoint does

Return the same generic message ("Invalid email or password") and similar timing whether the account exists or not, which limits enumeration; when the user is unknown, still run a hash verification against a dummy hash. Rate limit by account and by source (IP, device fingerprint) because stuffing spreads across IPs while spraying spreads across accounts. Hard lockout after N failures lets attackers lock out victims (a denial of service), so many systems prefer progressive delays, CAPTCHAs or step-up challenges, and notify the user. Follow NIST SP 800-63B guidance: favour length over composition rules, allow paste and password managers, check new passwords against breached-password lists, and do not force periodic rotation without evidence of compromise.

A login handler

Express-style TypeScript; rateLimiter, verifyPassword and audit are your own helpers.

const DUMMY_HASH = await hashPassword(crypto.randomUUID()); // computed once at startup

app.post('/login', async (req, res) => {
  const { email, password } = req.body;
  const key = `login:${email.toLowerCase()}`;

  if (!(await rateLimiter.allow(key)) || !(await rateLimiter.allow(`ip:${req.ip}`))) {
    return res.status(429).json({ error: 'Too many attempts. Try again later.' });
  }

  const user = await db.users.findByEmail(email);
  // verify against a dummy hash when the user is unknown to keep timing similar
  const ok = await verifyPassword(user?.passwordHash ?? DUMMY_HASH, password);

  if (!user || !ok) {
    audit('login_failed', { email, ip: req.ip });
    return res.status(401).json({ error: 'Invalid email or password' });
  }
  await rateLimiter.reset(key);
  await startSession(req, res, user); // regenerates the session id
  audit('login_succeeded', { userId: user.id, ip: req.ip });
  res.json({ ok: true });
});

Registration and reset leak too

Enumeration is not just a login problem. "This email is already registered" on sign-up, or a different reset message for unknown addresses, gives the same information away. Use neutral wording and send details by email instead.

त्वरित जाँच: What is a downside of hard account lockout after a few failed attempts?

  • It makes passwords easier to guess
  • Attackers can deliberately lock out legitimate users
  • It reveals the password hash
  • It disables HTTPS for that user
Answer

Attackers can deliberately lock out legitimate users — Lockout turns into a denial-of-service tool; progressive delays and step-up checks are gentler.