Skip to main content
友田 陽大
実践Webハッキング技法
セキュリティ
ホワイトハッカー
認証
脆弱性診断
Webセキュリティ

A complete conquest of authentication vulnerabilities [2026]: username enumeration, brute force, 2FA bypass, password reset — a version faithful to the official docs

An in-depth look at vulnerabilities and attack techniques in authentication (login) mechanisms, faithful to the PortSwigger Web Security Academy. Username enumeration (message differences, response-time differences), brute force and bypassing rate limits, account-lockout loopholes, multi-factor authentication (2FA/MFA) bypass, password-reset poisoning, Remember Me / password-change flaws, and root-cause defenses via rate limiting, constant responses, MFA, and safe reset design — explained strictly within your own lab.

Published
Reading time
6 min read
Author
友田 陽大
Share

Authentication is the front line of an app's security. If it's breached, the authorization and cryptography beyond it become meaningless. As PortSwigger says, "authentication vulnerabilities allow attackers access to sensitive data," and if a privileged account is taken, the whole app is hijacked. This article explains those attack techniques faithfully to the official source.

An absolute premise: brute force, enumeration, and reset poisoning all carry strong invasiveness. Execute only within a legal lab or a scope authorized in writing. Unauthorized login attempts are themselves an act of unauthorized access (→ the legal guide). The map is the pillar.


1. Username enumeration — the first stage of the attack

Before brute force, confirming "valid usernames that exist" makes efficiency jump. Apps often leak the existence of a user through slight differences.

Leak signalExample
Message difference"Invalid username" vs "Invalid password"
Response-time differenceOnly existing users trigger a hash check, so the response is slower
HTTP status / subtle wording differencePresence or absence of a trailing period, a different redirect target
# Burp Intruder で username を辞書にして送り、レスポンスの差分(長さ・文言・時間)を観察
POST /login HTTP/1.1
Host: lab.example
Content-Type: application/x-www-form-urlencoded

username=§candidate§&password=wrongpass

With a Sniper attack in Burp Intruder, cycle only the username position and pin down valid users from outliers in response length or response time.


2. Brute force and bypassing protections

Once a valid username is known, you brute-force the password. The problem is flaws in the protection mechanisms.

2.1 Bypassing IP-based rate limits

"Block after a certain number of failures from the same IP" can be bypassed by header spoofing or IP rotation.

# X-Forwarded-For を毎回変えて、IPベースのカウンタを欺く(脆弱な実装で有効)
X-Forwarded-For: 1.2.3.4

2.2 The account-lockout loophole — password spraying

"Lock after N failures for one user" is bypassed by password spraying — trying the same weak password once each against many users. Each user's failure count never reaches the lockout threshold.

# 縦に弱いパスワードを固定し、横に大量ユーザーを試す(Pitchfork/Cluster bomb的)
user001 : Password1!
user002 : Password1!
...                      ← どのユーザーもロックされない

Furthermore, the "you've been locked out" response itself becomes an enumeration signal that "this user exists."


3. Multi-factor authentication (2FA/MFA) bypass

MFA is powerful, but it works only when implemented correctly. Typical holes PortSwigger lists:

3.1 Missing verification logic (skipping the second stage)

When the session issued after the first stage (password) succeeds can reach protected resources even with the second stage incomplete. Skip the 2FA input screen and hit the destination URL directly, and it goes through.

# 2FAページを経由せず、ログイン後のページへ直接アクセスして通るか確認
GET /my-account HTTP/1.1
Host: lab.example
Cookie: session=<1段目だけ通したセッション>

3.2 OTP brute force

If the verification code (OTP) has no attempt limit or rate limit, you can brute-force the 4–6 digits. It can be broken just by cycling 00009999 in Burp Intruder.

3.3 Verifying the wrong user

An implementation mistake where the second-stage verification accepts a code for a different user than the first stage's user. It happens when account identification is left to the client.


4. Other mechanisms — reset, Remember Me, change

4.1 Password-reset poisoning (the back door)

Password reset "temporarily relaxes identity verification," so it easily becomes authentication's back door.

  • Guessable tokens: sequential, timestamp, or short tokens are predictable.
  • Host-header poisoning: if the reset-link generation uses the Host header, an attacker can send Host: evil.example and plant a link to the attacker's domain in the email sent to the victim. When the victim clicks, the token goes to the attacker.
  • Identifier swapping: if the username/userId in the reset-confirm request can be changed to someone else, you can set another person's password.
# Hostヘッダ汚染:被害者宛リセットメールのリンクが攻撃者ドメインを指すよう仕込む
POST /forgot-password HTTP/1.1
Host: evil-attacker.example          ← サーバーがこれを信頼してリンク生成すると致命的
Content-Type: application/x-www-form-urlencoded

username=victim

4.2 Remember Me / password change

If the "keep me logged in" token is guessable (a hash of the username, etc.), it's forged. If a password change doesn't verify the current password, it's used for persistence after session hijacking.


5. [Defender side] Root-cause defenses

Once you understand the attack surface, close it by design. The essence of PortSwigger and the OWASP Authentication Cheat Sheet:

// ✅ ユーザー名列挙を防ぐ:成否で「同一の」メッセージ・同等の処理時間を返す
async function login(username: string, password: string) {
  const user = await findUser(username);
  // ユーザーが存在しなくても必ずハッシュ照合を走らせ、応答時間を一定化(タイミング差を消す)
  const hash = user?.passwordHash ?? DUMMY_HASH;
  const ok = await verifyPassword(password, hash); // Argon2id 等
  if (!user || !ok) {
    // 列挙を許さない一定の文言(どちらが違うかを明かさない)
    throw new AuthError("ユーザー名またはパスワードが正しくありません");
  }
  // ...
}

Design principles:

  • Close enumeration: return the same message, equivalent response time, and same status for success and failure.
  • Robust rate limiting: per-account + global, not just per-IP. Don't trust X-Forwarded-For. Correct rate limiting on serverless is in the dedicated guide.
  • Implement MFA correctly: don't let it reach protected resources until the second stage is complete. Put an attempt limit on the OTP. The code should be short-lived, single-use, and bound to the first-stage user.
  • Make password reset safe: tokens that are unguessable (CSPRNG), long, short-lived, single-use, and user-bound. For link generation, don't use the Host header; trust the server-side canonical URL (a defense against HTTP Host header attacks).
  • Password strength and hashing: store with Argon2id, etc., and reject weak passwords. Details in the password-hashing/cryptography guide.
  • Sessions: regenerate the session ID after authentication, and add HttpOnly/Secure/SameSite.

For the choice of leaning the authentication foundation itself toward managed (Cognito/Auth0/Clerk/Supabase Auth), see authentication-platform selection. "Don't implement authentication yourself" is the safest call in many projects.


6. Summary

  • A two-stage enumerate→brute-force setup: first identify valid usernames from message and time differences.
  • Protection mechanisms get bypassed: IP limits by header spoofing, lockout by password spraying.
  • MFA depends on implementation: watch for second-stage skip, OTP brute force, and verifying the wrong user.
  • Reset is the back door: guessable tokens, Host-header poisoning, identifier swapping.
  • Root-cause defenses: close enumeration with constant responses + robust rate limiting + correct MFA + safe reset + strong hashing.

Next, head to the complete conquest of SSTI, which hijacks the template engine to reach RCE.


References (official primary sources)

友田

友田 陽大

Developer of a METI Minister's Award–winning product. With TypeScript + Python + AWS, I deliver SaaS, industry DX, and production-grade generative AI (RAG) end to end — from requirements to infrastructure and operations — single-handedly.

What if this attack were reproduced on your app?

Web-app vulnerability assessment & penetration testing

I actually reproduce and assess the SQLi, XSS, SSRF, JWT, auth, and SSTI attacks covered here on your app, and take it through from design to fix. Only those who know the attacker's moves can preempt where it breaks at the design stage. You're welcome to visualize the current state with the free OSS first.

Available for both project-based (contract) and advisory engagements. Start with a free 30-minute consult.

Also worth reading