Brute force detection

How to detect brute force login attacks

Guessing a password leaves a trail of failures. Count them in the right places, and the login that finally works stops looking like an ordinary sign-in.

What brute force looks like

Most login code only sees one attempt at a time. It checks the password, says yes or no, and forgets. A brute force attack is only visible across attempts: the same account failing again and again, or the same IP failing across many accounts. If you don't record the failures somewhere every server can see, you can't spot it.

Five signals of a brute force attack

1. Many failures on one account

Classic brute force: one account, many passwords. A person who forgot their password tries three or four times, then resets it. A script tries hundreds.

From a real attack on a LoginLlama customer: one account failed 35 times in 95 seconds from one IP. We flag more than 10 failures in 5 minutes.

2. One IP failing on many accounts

Password spraying turns brute force sideways: one common password against many accounts, so no single account sees enough failures to lock. Count distinct accounts per IP instead.

One IP in Cairo failed on 7 accounts in 4 minutes. Schools and offices share an IP between a handful of users, so we flag more than 10 accounts in 10 minutes.

3. The success after the failures

The failures are noise. The login that matters is the correct password straight after them, from the same place. That is a guessed password, and it should not get a session without a second check.

After a burst, every check from that IP for that account is flagged for an hour, success or not.

4. Admin accounts get fewer tries

An admin account is worth far more to whoever guesses it, and the people who own one rarely mistype ten times. Give privileged accounts a much lower limit.

With privileged: true, three failures are enough to flag the account rather than ten.

5. Where the attempts come from

Brute force runs from servers, not living rooms. Failures from hosting networks, known VPN exits, Tor and IPs with a record of abuse deserve less patience than failures from a home broadband line.

A burst from a data centre ASN with a user agent like python-requests is a script, whatever the password.

Report failures, act on the success

LoginLlama counts failures across every server you run, so you don't have to. Send each attempt with its outcome. A success after a burst comes back with after_failure_burst, and an IP spraying your users comes back with ip_password_spraying.

sign-in.ts
// Report every attempt, not only the good ones. The failures are
// what reveal a brute force attack.
import { LoginLlama } from 'loginllama';

const loginllama = new LoginLlama({ apiKey: process.env.LOGINLLAMA_API_KEY });

export async function signIn(req, email, password) {
  const user = await verifyPassword(email, password);

  if (!user) {
    await loginllama.reportFailure(email, { request: req });
    return { error: 'Wrong email or password' };
  }

  const check = await loginllama.reportSuccess(email, {
    request: req,
    privileged: user.role === 'admin'
  });

  // after_failure_burst: the right password straight after a run of guesses.
  if (check.codes.includes('after_failure_burst') || check.risk_score > 5) {
    return { challenge: 'email_code' };
  }

  return { user };
}

Fails open: if LoginLlama can't be reached in two seconds, the sign-in carries on. The first 1,000 checks are free. Get an API key.

Brute force detection FAQ

What is a brute force login attack?

An attacker tries password after password against an account until one works. Simple versions hit one account from one IP. Password spraying tries a few common passwords against many accounts so no single account sees many failures.

How is brute force different from credential stuffing?

Brute force guesses passwords. Credential stuffing replays real email and password pairs from other sites’ breaches, usually one try per account. Brute force shows up as many failures on an account or from an IP. Stuffing shows up as many accounts from many IPs, each tried once or twice.

Is account lockout enough?

Lockout stops the simplest attack and creates a new one: anyone can lock your users out by failing on purpose. Spraying never trips it either. Flagging the account and asking for a second check on the next success protects the account without handing attackers a way to deny service.

Should admin accounts have different rules?

Yes. An admin account is the one an attacker wants most, and real admins rarely fail many times in a row. A lower failure limit and stricter scoring for admins costs almost nothing in false alarms.