Back to Guides

    API2:2023 - Broken Authentication

    Broken Authentication happens when an API implements login, session, token, or identity flows incorrectly. Attackers can abuse these flaws to impersonate users, replay session material, or maintain unauthorized access.

    1. What Is It?

    Broken Authentication happens when an API implements authentication incorrectly, allowing attackers to compromise identity, abuse session flows, or authenticate as another user.

    This category is broader than login alone. It includes flaws in token issuance, refresh logic, credential recovery, MFA handling, session invalidation, and account lifecycle behavior.

    In the previous guide, we covered Broken Object Level Authorization and how authorization failures happen after identity is already established.

    Read the BOLA Guide

    2. Why It Matters

    Broken Authentication is dangerous because:

    • It allows attackers to become valid users in the system.
    • It can lead directly to account takeover.
    • It affects every protected API behind the compromised identity.
    • A flaw in token or session logic can undermine otherwise secure endpoints.

    In real-world systems, this can lead to:

    • Credential stuffing success at scale.
    • Session replay and token theft abuse.
    • Password reset compromise.
    • Persistent unauthorized access through stale sessions.

    Why OWASP classifies it as API2

    APIs rely heavily on programmatic authentication, usually with tokens, session material, or delegated identity flows. If these mechanisms are implemented incorrectly, attackers can impersonate users, replay old credentials, or keep access longer than intended. This is why OWASP places Broken Authentication at the core of API security risk.

    3. How It Happens (Technical)

    Broken Authentication happens when the API accepts identity-related inputs correctly in principle, but fails to secure the full authentication lifecycle.

    That lifecycle includes login, token issuance, refresh, logout, password reset, MFA verification, and session invalidation.

    Common technical causes:

    • Weak or missing rate limiting on login endpoints
    • Long-lived or replayable access tokens
    • Refresh tokens that are not rotated or revoked safely
    • Password reset flows that trust attacker-controlled input
    • MFA flows that can be skipped, downgraded, or bypassed

    Core Issue

    auth/refresh.py
    # vulnerable
    def refresh_token(payload):
        session = REFRESH_SESSIONS.get(payload.refresh_token)
        if not session:
            raise Unauthorized()
    
        # revoked state exists, but is not enforced
        session["revoked"] = True
        return issue_new_token_pair(session["email"])
    A refresh token marked as revoked is still accepted and can continue minting new sessions.

    Correct Direction

    auth/refresh.py
    # safer
    def refresh_token(payload):
        session = REFRESH_SESSIONS.get(payload.refresh_token)
        if not session:
            raise Unauthorized()
    
        if session["revoked"]:
            raise Unauthorized()
    
        session["revoked"] = True
        return issue_new_token_pair(session["email"])
    Refresh tokens must be rejected once revoked or previously used in a rotation flow.

    Key concept: authentication security does not end after login. If old session material remains valid, identity can be replayed even when access tokens are short-lived.

    Attacker’s Perspective

    From an attacker’s perspective, Broken Authentication is not limited to guessing passwords. It is about finding a weaker way into a valid session.

    • Attack login endpoints with brute force or credential stuffing
    • Replay stolen or leaked access and refresh tokens
    • Probe password reset and MFA flows for downgrade paths
    • Check whether logout or token rotation really invalidates sessions

    If stale or revoked authentication material still works, the attacker does not need to guess credentials again.

    4. Real-World Example

    Broken Authentication can affect login, token issuance, MFA, password reset, and session lifecycle flows.

    One concrete example is refresh token reuse, where an old or revoked refresh token is still accepted by the API and can mint a new authenticated session.

    Example endpoint:

    POST /api/auth/refresh

    Expected behavior: once a refresh token is rotated or revoked, it should no longer be accepted.

    Vulnerable Logic

    api/auth_refresh.py
    session = REFRESH_SESSIONS.get(payload.refresh_token)
    if not session:
        raise Unauthorized()
    
    # revocation state is ignored
    session["revoked"] = True
    rotated_refresh = create_refresh_token(user)
    
    return {
        "access_token": create_access_token(user),
        "refresh_token": rotated_refresh,
    }
    The handler finds the session, but never rejects already revoked refresh material.

    What is wrong: the API tracks revocation state, but does not enforce it. A previously invalidated refresh token can be replayed to obtain a fresh access token.

    Example attack flow:

    1. Login as a low-privilege user.
    2. Obtain a stale or revoked refresh token.
    3. Send it to POST /api/auth/refresh.
    4. Receive a new access token from replayed session material.
    5. Use that session to reach protected data.

    In this benchmark, a revoked admin refresh token is intentionally exposed through a debug field to make the exploit path deterministic. In real systems, stale refresh tokens may leak through logs, debug endpoints, browser storage, analytics pipelines, or compromised clients.

    Result: even though the token should be dead, it still creates a live authenticated session. That is a session replay flaw inside the authentication lifecycle.

    Common Variations

    • Credential Stuffing: leaked username-password pairs are replayed against login APIs at scale.
    • Weak Token Validation: expired, malformed, forged, or replayed tokens are still accepted.
    • Refresh Token Reuse: revoked or previously used refresh tokens continue to mint fresh sessions.
    • Password Reset Abuse: recovery flows trust attacker-controlled input or leak whether an account exists.
    • MFA Bypass: the second factor exists but can be skipped, downgraded, or validated inconsistently.

    5. How To Prevent

    1. Treat authentication as a lifecycle, not a single login event

    Securing login is not enough. Protect token issuance, refresh, reset, MFA, logout, and session invalidation with the same rigor.

    2. Rotate and revoke refresh tokens correctly

    Refresh tokens should be one-time or rotation-based and immediately rejected after use or revocation.

    auth/rotation.py
    def refresh_session(refresh_token):
        session = validate_refresh_token(refresh_token)
    
        if session.revoked:
            raise Unauthorized()
    
        session.revoked = True
        return issue_new_token_pair(session.user_id)
    If the token has already been used or revoked, it must not create a new session.

    3. Use short-lived access tokens

    Access tokens should expire quickly so leaked tokens have limited value.

    auth/access_tokens.py
    access_token = issue_access_token(
        user_id=user.id,
        expires_in_minutes=15
    )
    Short-lived access tokens reduce the blast radius of token leakage.

    4. Protect recovery and MFA flows

    Password reset and MFA are part of authentication and must be protected accordingly.

    • Expire reset tokens quickly
    • Bind recovery to verified channels
    • Do not leak whether an account exists
    • Do not allow MFA downgrade without strong proof

    5. Centralize authentication controls

    Do not spread token validation, revocation logic, and MFA enforcement across unrelated handlers.

    Instead:

    • Centralize token issuance and validation
    • Use consistent revocation logic
    • Apply shared auth middleware where appropriate
    • Log suspicious authentication behavior and replay attempts

    Key Principle

    • Protect the full authentication lifecycle
    • Assume tokens can be leaked or replayed
    • Design for revocation, rotation, and failure states
    • Invalidate old session material aggressively

    6. Detection Tips (Scanner Perspective)

    Detecting Broken Authentication requires testing identity workflows, not just protected business endpoints.

    Common techniques:

    • Brute-force and credential stuffing simulation
    • Replay testing for access and refresh tokens
    • Expired token and malformed token validation checks
    • Refresh rotation and revocation verification
    • Password reset and MFA workflow tampering

    Key signal: if an old, revoked, expired, or previously used session artifact can still produce access, Broken Authentication is present.

    7. Final Takeaway

    Broken Authentication is not just a login bug.

    It exists whenever:

    • Authentication attempts are weakly protected
    • Tokens are replayable or overtrusted
    • Refresh and revocation logic are incomplete
    • Recovery or MFA flows can be abused

    Every authentication flow should answer: Can stale, leaked, or replayed identity material still create a trusted session?

    If the answer is yes, the API is already exposed.