GraphNode
Back to OWASP Top 10 hub
OWASP A07

OWASP A07:2021 Identification and Authentication Failures

| 11 min read |GraphNode Research

TL;DR

A07:2021 Identification and Authentication Failures is the renamed and broadened successor to A02:2017 Broken Authentication. It covers any flaw in how users prove who they are or in how their authenticated session is managed: credential stuffing exposure, weak password policy, missing multi-factor authentication, session fixation, JWT misuse, missing logout invalidation, predictable session identifiers, and hardcoded credentials. Detection requires layered tooling: SAST flags hardcoded credentials, weak password validation patterns, JWT signature gaps, and session-fixation code shapes; DAST verifies runtime brute-force protection, session reuse, and MFA bypass. Prevention follows NIST SP 800-63B: long passphrases checked against breach corpora, modern password hashing (Argon2, bcrypt, scrypt), MFA on sensitive operations, and migration toward passkeys and WebAuthn.

Authentication is the front door of every application that holds user data. When the lock is weak, every other security control downstream becomes contingent on the attacker not bothering to walk in. OWASP's 2021 Top 10 redesign acknowledged that authentication failures had grown beyond the narrower scope of the 2017 edition: identity proofing, session lifecycle, recovery flows, and machine-to-machine credentials all needed to sit under one umbrella. A07:2021 is that umbrella. It dropped from second place in 2017 to seventh in 2021 — but the move is a story about better identity libraries reaching the mainstream, not about the category becoming less dangerous. Account takeover (ATO) attacks remain one of the most common breach vectors observed in industry reports.

The rename from "Broken Authentication" to "Identification and Authentication Failures" is not cosmetic. Identification is the assertion of who someone is — the username, the device certificate, the API key. Authentication is the verification of that assertion — the password check, the signature validation, the MFA prompt. The 2021 edition pulled both into the same category because the failure modes overlap: a weak username-enumeration flow leaks identification, a missing rate limit weakens authentication, and either alone is enough to enable credential stuffing at scale. This guide walks the category in depth: definition, common patterns, real incidents, the CWE mappings that show up in scanner output, and the layered detection and prevention that actually works.

What A07 Covers

A07:2021 covers any defect in the lifecycle that begins with a user (or service) asserting an identity and ends with a session being established, refreshed, and ultimately invalidated. That lifecycle has more moving parts than a typical login form suggests. There is the credential check itself — password verification, certificate validation, OAuth token introspection. There is the session establishment — generating a session identifier, binding it to the request context, setting cookie flags. There is the ongoing trust during the session — how often the credential is re-verified, how privilege changes propagate, how the session resists fixation and theft. And there is the destruction of the session — logout, idle timeout, absolute timeout, revocation when a password changes.

This is broader than the 2017 "Broken Authentication" category, which was scoped largely to login flows and session management. The 2021 rename pulled in identification weaknesses — username enumeration, predictable account identifiers, machine-identity flaws like hardcoded API keys — that had previously been treated as adjacent rather than core. A perfectly implemented password check is still a A07 failure if the registration flow leaks which usernames exist, or if the password reset link is reusable, or if a service-to-service API key is committed to a public repository. The category is identity lifecycle broadly construed.

A07 sits adjacent to A01 Broken Access Control but is distinct. A01 answers "what is this authenticated user allowed to do?" — authorization. A07 answers "is this really the user they claim to be, and is this session still trustworthy?" — authentication. A correctly authenticated user can still trigger A01; a correctly authorized policy can still be defeated by a A07 session-fixation flaw. The two categories are split because the controls and the detection layers differ.

Common Patterns

Credential stuffing. Attackers take username-and-password pairs leaked from one breach and replay them against another service, betting on password reuse. With billions of credentials available on dark-web markets and free credential-stuffing tools that handle CAPTCHA evasion, the cost per attempt approaches zero. Any login endpoint without rate limiting, MFA, or breach-corpus checks is vulnerable by default.

Brute-force and password spraying. Brute-force iterates many passwords against one account; password spraying iterates one or two common passwords (Spring2026!, Welcome123) against many accounts to evade per-account lockouts. Both work against any endpoint that does not enforce rate limiting at the IP, account, and credential-pair level.

Weak password policy. Accepting short passwords, dictionary words, or previously breached credentials. NIST SP 800-63B has explicitly moved away from forced-complexity rules toward minimum length plus breach-corpus screening — the modern guidance is to allow long passphrases and check candidates against the Have I Been Pwned database, not to require uppercase-symbol-digit mixes that produce predictable patterns.

Session fixation. The application accepts a session identifier supplied by the client (via URL parameter, hidden form field, or pre-set cookie) and binds the authenticated session to that identifier. An attacker who pre-supplies the identifier can hijack the session after the victim logs in. The fix is to regenerate the session identifier on every privilege change, especially at login.

Missing logout invalidation. The application clears the cookie on the client but does not invalidate the session on the server. Anyone who captured the session token earlier — through XSS, network capture, or a shared device — can continue to use it after the user logs out. Logout must destroy server-side state, not just client-side cookies.

Session ID in URL. Session identifiers exposed in the URL leak through the browser history, server logs, referrer headers, and shoulder-surfing. The fix is to keep session identifiers in cookies marked HttpOnly, Secure, and SameSite.

Weak password reset flow. Reset tokens that do not expire, that are too short to resist guessing, that are reusable, or that are sent over an insecure channel. Reset flows that reveal whether an email is registered enable username enumeration. The reset flow is often the weakest part of an otherwise solid auth system.

JWT none algorithm and unverified signatures. The infamous "alg": "none" JWT bypass, where a server accepts a token whose header declares no signature algorithm and validates it accordingly. More broadly: any code path that decodes a JWT and trusts its claims without verifying the signature against the expected key. The token becomes a freely-forgeable identity assertion.

Hardcoded credentials. API keys, database passwords, signing secrets, and service tokens committed to source control or embedded in compiled binaries. Once disclosed, they are valid until rotated — and rotation across a fleet is operationally painful, so they often persist. CWE-798 captures this pattern explicitly. See secret scanning for the dedicated detection layer.

Missing MFA on sensitive operations. Strong MFA at login is necessary but not sufficient. High-impact operations — changing email, disabling MFA itself, exporting data, transferring funds — should require step-up authentication, not just a valid session. A session-hijack attacker with a stolen cookie should not be able to silently disable MFA on the account they just took over.

Real-World Incidents

LinkedIn (2012, fully disclosed in 2016). Approximately 6.5 million password hashes were leaked in 2012; in 2016 a much larger 117-million-record dump from the same breach surfaced. The hashes were unsalted SHA-1 — a fast hash designed for integrity, not password storage. With no salt, attackers built a single rainbow table and cracked the vast majority of passwords offline. The incident is still cited as the textbook example of why password storage requires a slow, salted, memory-hard function (Argon2, bcrypt, scrypt) rather than a general-purpose hash. Reused LinkedIn passwords seeded credential stuffing campaigns for years afterward.

Twitter (2018). Twitter disclosed that an internal logging bug had written user passwords in plaintext to internal logs before the hashing step. The exposure was internal and Twitter said it had no evidence of abuse, but the company asked roughly 330 million users to change their passwords. The lesson is operational: even with correct hashing in the storage path, an upstream logging mistake can defeat the entire control. Log-redaction discipline is part of the authentication program, not a separate concern.

Capital One (2019) — credential stuffing element. The Capital One breach is most often discussed for its SSRF and IAM-misconfiguration chain, but the broader industry-level story it sat within was the rise of automated credential abuse against financial services. Industry reports through the late 2010s and into the 2020s consistently showed credential stuffing as one of the highest-volume attack categories observed against authentication endpoints. Capital One's case is one of many that drove the move toward MFA-by-default and breach-corpus checks at registration.

The general ATO trend. Account takeover attacks — driven by credential stuffing, weak password reset flows, and session theft — have remained one of the most commonly reported breach categories in industry threat reports throughout the 2020s. The mitigations that work are well known: MFA, breach-corpus password checks, anomaly detection on login signals, and disciplined session management. The fact that ATO remains common reflects how often these mitigations are still missing in production code, not that the defenses are unknown.

Relevant CWE Mappings

A07:2021 aggregates a broad set of underlying CWEs covering identification, credential storage, session management, and brute-force protection. The six below are the most common in practice and the ones most teams will recognize from scanner output and finding tickets.

CWETitleWhere It Shows Up
CWE-287Improper AuthenticationGeneral catch-all for missing or weak verification of identity claims
CWE-307Improper Restriction of Excessive Authentication AttemptsLogin endpoint without rate limiting or account lockout — the brute-force enabler
CWE-384Session FixationApplication accepts a client-supplied session ID and binds it to the new authenticated session
CWE-521Weak Password RequirementsPolicy that accepts short, dictionary, or breach-corpus passwords
CWE-613Insufficient Session ExpirationSessions that do not idle out, do not absolute-time-out, or persist after logout
CWE-798Use of Hardcoded CredentialsAPI keys, passwords, signing secrets embedded in source or compiled binaries

CWE-287 is the umbrella the others descend from when a finding does not fit a more specific entry. CWE-798 (hardcoded credentials) is the entry most directly visible to source-level static analysis, which is why secret scanning has become a standard first-line control. CWE-307 (missing brute-force protection) and CWE-613 (insufficient session expiration) are the runtime entries DAST is best positioned to confirm.

Detection: Where SAST and DAST Each Help

A07 spans both code-level patterns visible in source and runtime behavior that only manifests against a deployed system. No single layer catches the full category. A complete program runs SAST in CI to catch the source-visible defects early and DAST in staging to verify runtime enforcement.

SAST is strongest where the defect is visible at the source level. A static analyzer can flag hardcoded credentials, API keys, and signing secrets directly (CWE-798). It can detect weak password validation patterns — minimum length below the policy bar, missing breach-corpus checks, deprecated hash functions like MD5 or SHA-1 used for password storage. It catches JWT decoding paths that do not verify the signature, and JWT verification calls that pass the unverified header algorithm into the verifier (the none-algorithm bypass shape). It catches session-fixation patterns where a client-supplied session identifier is bound to authenticated state. It flags missing logout invalidation when the logout handler clears a cookie without invalidating the server-side session record. GraphNode SAST traces these patterns across method boundaries with interprocedural data flow analysis. SAST cannot fully detect runtime session weaknesses — whether the deployed server actually rate-limits, whether session identifiers are predictable in practice, whether the MFA prompt is actually enforced for the action it should gate.

DAST is the layer that confirms runtime enforcement. A properly configured DAST scanner can submit thousands of failed login attempts and observe whether the endpoint rate-limits or locks out (CWE-307 verification). It can capture two session identifiers and analyze their entropy to detect predictability. It can replay a session token after the user logs out and observe whether the server still accepts it (CWE-613 verification). It can submit tampered JWTs — including the "alg": "none" case — and observe whether the server still trusts them. It can attempt sensitive actions through a hijacked session to verify whether step-up MFA is actually enforced. DAST closes the gap between "the code looks correct" and "the deployed system actually enforces the policy."

Manual review remains the layer that catches business-logic flaws in the identity flow: a multi-step recovery process that allows step-skipping, a registration flow that races a password reset, a federated-identity bridge that trusts an upstream IdP claim it should not. These need a human reviewer who understands the intended flow.

Prevention

Strong password policies (NIST SP 800-63B style). Enforce a minimum password length of at least 8 characters (NIST recommends supporting up to 64 or more). Drop forced complexity rules that produce predictable patterns. Screen candidate passwords against a breach corpus — Have I Been Pwned exposes a k-anonymity API that lets you check without sending the full password. Allow paste in password fields. Allow Unicode. Modern policy is "longer and not breached," not "uppercase-digit-symbol mix."

Use a slow password hash. Argon2id is the OWASP-recommended choice; bcrypt and scrypt remain acceptable. Never store passwords with general-purpose fast hashes (MD5, SHA-1, plain SHA-256) — these were designed for integrity, not for resisting offline cracking, and the LinkedIn 2012 breach is the textbook lesson. Always salt per-user. Tune the work factor so a single hash takes tens to hundreds of milliseconds on production hardware.

Multi-factor authentication for sensitive operations. Require MFA at login for privileged accounts and at minimum prompt for it on sensitive operations: changing email, changing password, disabling MFA itself, adding payment methods, exporting data. WebAuthn-based authenticators (security keys, platform authenticators) defeat phishing in a way that SMS and TOTP cannot. SMS MFA is better than no MFA but is the weakest factor due to SIM-swap risk.

Server-side session management. Generate session identifiers with a cryptographically secure random source — at least 128 bits of entropy. Store sessions server-side; do not embed sensitive state in client-readable cookies. Set the cookie flags HttpOnly, Secure, and SameSite=Lax or SameSite=Strict. Regenerate the session identifier on every privilege change, especially at login (defeats session fixation). Invalidate the server-side session on logout and on password change.

Rate limiting and account-lockout with care. Rate-limit at the IP, the account, and the credential-pair level. Aggressive per-account lockout is a denial-of-service vector — an attacker can lock every named account just by failing logins. Modern guidance leans toward layered rate limiting plus CAPTCHA escalation rather than hard lockouts. Always log authentication failures at a level that supports SIEM correlation. See OWASP A09 for the logging side of this control.

Password leak checks. At registration, password change, and ideally at next login, check the new password against a breach corpus (Have I Been Pwned). If the password appears in a known breach, refuse it. This single control defeats credential stuffing more effectively than any other input-side check.

Migrate toward passkeys and WebAuthn. Passkeys eliminate the password as a shared secret, replacing it with a per-site keypair stored in the user's authenticator. They cannot be phished, cannot be reused across sites, and cannot be brute-forced. The 2026 industry trajectory is clearly toward passkey adoption as the default for new applications and as a parallel option for existing ones. Adding passkey support today reduces the population of accounts that are ever exposed to credential-stuffing.

Where GraphNode SAST Fits

GraphNode SAST covers the source-visible part of A07 with deep interprocedural data flow analysis across 13+ languages. The strongest area is hardcoded credentials (CWE-798) — API keys, database passwords, JWT signing secrets, and service tokens flagged directly in source with file and line, before they ever reach a built artifact. The detection complements a dedicated secret scanning layer in CI, which sweeps git history for previously committed secrets. The two are not redundant: SAST catches credentials in the current code, secret scanning catches credentials that landed historically.

Beyond hardcoded credentials, GraphNode SAST flags weak password validation patterns (deprecated hash functions used for password storage, minimum-length checks below policy), JWT decoding paths that do not verify the signature, JWT verification calls that pass the header algorithm into the verifier rather than fixing it (the none-algorithm shape), session-fixation patterns where client-supplied session identifiers are bound to authenticated state, and missing-invalidation patterns in logout handlers. These are the code-level shapes that cause A07 findings in production today.

What SAST cannot do for this category is verify runtime behavior. Whether the deployed server actually rate-limits, whether session entropy holds in practice, whether MFA is actually prompted on the operation it should gate — these need DAST in staging and disciplined production telemetry. The honest position is that GraphNode SAST is one strong layer in a multi-layer A07 program, not the whole program. For the broader picture of how the layers fit together, see the OWASP Top 10 hub.

Frequently Asked Questions

What are identification and authentication failures?

Identification and authentication failures (OWASP A07:2021) are any defect in how users prove who they are or in how their authenticated session is managed. The category covers credential stuffing exposure, weak password policy, missing multi-factor authentication, session fixation, JWT misuse, missing logout invalidation, predictable session identifiers, hardcoded credentials, and weak password reset flows. It is the renamed and broadened successor to A02:2017 Broken Authentication, with the rename pulling identification weaknesses (username enumeration, machine-identity flaws) into the same scope as authentication weaknesses.

Why was Broken Authentication renamed to Identification and Authentication Failures?

The 2017 category "Broken Authentication" was scoped largely to login flows and session management. The 2021 rename to "Identification and Authentication Failures" pulled in identification weaknesses — username enumeration, predictable account identifiers, machine-identity flaws like hardcoded API keys — that had previously been treated as adjacent rather than core. Identification is the assertion of who someone is; authentication is the verification of that assertion. The 2021 edition treats both as one lifecycle because the failure modes overlap and the controls are interdependent.

What is credential stuffing?

Credential stuffing is an attack where adversaries take username-and-password pairs leaked from one breach and replay them against another service, betting on password reuse. With billions of credentials available on dark-web markets and free credential-stuffing tools, the cost per attempt approaches zero. The defenses are layered: rate limiting at IP, account, and credential-pair level; breach-corpus checks at registration and password change (Have I Been Pwned); MFA on login and step-up MFA on sensitive operations; and longer-term migration to passkeys, which eliminate the reusable shared secret entirely.

Can SAST detect authentication failures?

SAST detects A07 partially, not fully. It is well positioned to flag hardcoded credentials (CWE-798), weak password validation patterns including deprecated hash functions used for password storage, JWT decoding paths that do not verify the signature, JWT verification calls vulnerable to the alg-none bypass, session-fixation patterns where client-supplied session identifiers are bound to authenticated state, and missing-invalidation patterns in logout handlers. SAST cannot verify runtime session weaknesses such as actual rate-limit enforcement, session-identifier entropy in practice, or MFA prompts on sensitive operations. Complete coverage requires SAST plus DAST plus design review.

What does NIST SP 800-63B recommend for password policy?

NIST SP 800-63B has explicitly moved away from forced-complexity rules toward minimum length plus breach-corpus screening. The modern guidance is to require at least 8 characters (with support for 64 or more), to allow long passphrases, to allow Unicode, to allow paste in password fields, and to screen candidate passwords against a known-breach list rather than enforcing uppercase-symbol-digit complexity. NIST also recommends against forced periodic password rotation in the absence of evidence of compromise, since forced rotation produces predictable mutation patterns that weaken security.

Detect Hardcoded Credentials and Weak Auth Patterns in Source Code

GraphNode SAST flags hardcoded API keys and signing secrets, deprecated password hashes, JWT signature gaps, and session-fixation patterns across 13+ languages with deep interprocedural data flow analysis.

Request Demo