<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: implementing-api-authentication-hardening
description: >-
  Harden API authentication mechanisms by testing and implementing secure
  token management, OAuth flows, API key rotation, MFA enforcement, and
  session security controls.
domain: cybersecurity
subdomain: api-security
tags:
  - authentication
  - api-security
  - owasp-api2
  - oauth
  - jwt
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1078", "T1550"]
  owasp-api: ["API2"]
  tools: ["curl", "burp-suite", "nuclei", "jwt-tool"]
---

# Implementing API Authentication Hardening

## Overview

Broken Authentication (OWASP API2:2023) encompasses weak token generation,
missing credential rotation, insecure OAuth implementations, and absent MFA.
Attackers exploit these to assume user identities, bypass access controls,
and maintain persistent unauthorized access.

## Prerequisites

- Tools: ["curl", "burp-suite", "nuclei", "jwt-tool"]
- Test accounts with valid credentials
- Access to authentication configuration
- Authorized testing engagement with written scope

## Key Concepts

- **JWT weaknesses**: None algorithm, weak signing keys, missing expiry
- **OAuth misconfigurations**: Open redirects, PKCE bypass, token leakage
- **API key security**: Rotation, scoping, transmission security
- **Session management**: Token lifetime, revocation, concurrent sessions

## Workflow

### Step 1: JWT Security Assessment

```bash
# Decode JWT without verification
echo "$JWT_TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | jq .

# Test None algorithm bypass
python3 -c "
import base64, json
header = base64.urlsafe_b64encode(json.dumps({'alg':'none','typ':'JWT'}).encode()).rstrip(b'=')
payload = base64.urlsafe_b64encode(json.dumps({'sub':'admin','role':'admin','exp':9999999999}).encode()).rstrip(b'=')
print(f'{header.decode()}.{payload.decode()}.')
"

# Test with jwt_tool
jwt_tool "$JWT_TOKEN" -M at  # All tests
jwt_tool "$JWT_TOKEN" -C -d /usr/share/wordlists/rockyou.txt  # Crack key
jwt_tool "$JWT_TOKEN" -X a   # Alg none attack

# Verify token expiration enforcement
curl -s -H "Authorization: Bearer $EXPIRED_TOKEN" \
  https://target.com/api/users/me | jq .
```

### Step 2: Test Token Lifecycle

```bash
# Test token after password change
OLD_TOKEN="$TOKEN"
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"oldPassword":"old","newPassword":"new"}' \
  https://target.com/api/users/me/password

# Old token should be invalidated
curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer $OLD_TOKEN" \
  https://target.com/api/users/me

# Test token after logout
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  https://target.com/api/logout

curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer $TOKEN" \
  https://target.com/api/users/me

# Test refresh token rotation
curl -s -X POST -H "Content-Type: application/json" \
  -d "{\"refresh_token\":\"$REFRESH_TOKEN\"}" \
  https://target.com/api/token/refresh | jq .
```

### Step 3: OAuth Security Testing

```bash
# Test for open redirect in authorization endpoint
curl -sI "https://target.com/oauth/authorize?\
client_id=CLIENT&redirect_uri=https://evil.com&response_type=code&scope=read"

# Test PKCE bypass — send without code_verifier
curl -s -X POST -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&code=$AUTH_CODE&\
client_id=CLIENT&redirect_uri=https://target.com/callback" \
  https://target.com/oauth/token

# Test token scope escalation
curl -s -X POST -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&scope=admin:write" \
  -u "client_id:client_secret" \
  https://target.com/oauth/token | jq '.scope'
```

### Step 4: API Key Security Audit

```bash
# Check if API key works in URL (should be rejected)
curl -s -o /dev/null -w "%{http_code}" \
  "https://target.com/api/data?api_key=$API_KEY"

# Test key scope — try accessing out-of-scope endpoints
curl -s -o /dev/null -w "%{http_code}" \
  -H "X-API-Key: $READ_ONLY_KEY" \
  -X DELETE https://target.com/api/users/123

# Check key entropy
python3 -c "
import math, string
key = '$API_KEY'
charset = len(set(key))
entropy = len(key) * math.log2(charset) if charset > 0 else 0
print(f'Key length: {len(key)}, Charset: {charset}, Entropy: {entropy:.1f} bits')
print('WEAK' if entropy < 128 else 'ACCEPTABLE')
"
```

## Detection Opportunities

| Signal | Source | Description |
|--------|--------|-------------|
| JWT None algorithm | API gateway | Tokens with alg=none |
| Expired token usage | Auth logs | Requests with expired tokens accepted |
| Token reuse after revocation | Application logs | Revoked tokens still valid |
| Brute force on auth endpoints | WAF | High volume authentication failures |

```yaml
title: JWT Algorithm Manipulation Attempt
id: f6a7b8c9-d0e1-2345-fabc-456789012345
status: experimental
description: Detects JWT tokens with none algorithm or suspicious algorithm changes
logsource:
  category: application
detection:
  selection:
    jwt_algorithm:
      - none
      - None
      - NONE
      - nOnE
    event_type: authentication
  condition: selection
falsepositives:
  - Internal services using unsigned tokens in trusted networks
level: critical
tags:
  - attack.t1078
  - attack.initial_access
```

## Verification

- [ ] JWT algorithm validation enforced (reject none, HS256 on RS256 keys)
- [ ] Token expiration strictly enforced
- [ ] Tokens invalidated on password change and logout
- [ ] Refresh token rotation implemented
- [ ] OAuth redirect_uri strictly validated
- [ ] API keys transmitted only via headers (not URL parameters)

## References

- [OWASP API2:2023 — Broken Authentication](https://owasp.org/API-Security/editions/2023/en/0xa2-broken-authentication/)
- [JWT Security Best Practices — RFC 8725](https://www.rfc-editor.org/rfc/rfc8725)
- [MITRE ATT&CK T1078 — Valid Accounts](https://attack.mitre.org/techniques/T1078/)
