<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: implementing-api-versioning-security
description: >-
  Implement secure API versioning strategies and test for vulnerabilities
  in deprecated versions, version rollback attacks, and inconsistent security
  controls across API versions.
domain: cybersecurity
subdomain: api-security
tags:
  - api-versioning
  - api-security
  - deprecated-api
  - version-rollback
  - shadow-api
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1190", "T1195"]
  owasp-api: ["API9"]
  tools: ["curl", "ffuf", "burp-suite", "nuclei"]
---

# Implementing API Versioning Security

## Overview

APIs frequently maintain multiple versions simultaneously. Older versions
often lack security patches, rate limiting, or authentication controls that
were added to newer versions. OWASP API9:2023 Improper Inventory Management
covers risks from undocumented and deprecated API versions running in
production.

## Prerequisites

- Tools: ["curl", "ffuf", "burp-suite", "nuclei"]
- Knowledge of current API version scheme
- Access to API documentation for version history
- Authorized testing engagement with written scope

## Key Concepts

- **Version rollback**: Using older API versions to bypass newer security controls
- **Shadow APIs**: Undocumented or forgotten API versions still accessible
- **Deprecation gaps**: Security controls not backported to old versions
- **Version discovery**: Finding all accessible API versions

## Workflow

### Step 1: Discover API Versions

```bash
# Enumerate version prefixes in URL path
ffuf -u "https://target.com/api/vFUZZ/users" \
  -w <(seq 1 20) -mc 200,301,302,403 -o versions.json -of json

# Test common versioning patterns
PATTERNS=(
  "/api/v1/users" "/api/v2/users" "/api/v3/users"
  "/v1/api/users" "/v2/api/users"
  "/api/users?version=1" "/api/users?version=2"
  "/api/users?api-version=2024-01-01"
  "/api-v1/users" "/api-v2/users"
)
for P in "${PATTERNS[@]}"; do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    -H "Authorization: Bearer $TOKEN" \
    "https://target.com$P")
  [ "$STATUS" != "404" ] && echo "$P: HTTP $STATUS"
done

# Header-based versioning
for V in 1 2 3; do
  curl -s -o /dev/null -w "Accept v$V: %{http_code}\n" \
    -H "Authorization: Bearer $TOKEN" \
    -H "Accept: application/vnd.target.v$V+json" \
    https://target.com/api/users
done

# Custom version header
for V in 1 2 3 "2024-01-01" "2023-01-01" "2022-01-01"; do
  curl -s -o /dev/null -w "API-Version $V: %{http_code}\n" \
    -H "Authorization: Bearer $TOKEN" \
    -H "API-Version: $V" \
    https://target.com/api/users
done
```

### Step 2: Compare Security Controls Across Versions

```bash
# Test rate limiting on old vs new version
echo "--- v1 (old) ---"
for i in $(seq 1 50); do
  curl -s -o /dev/null -w "%{http_code} " \
    -H "Authorization: Bearer $TOKEN" \
    "https://target.com/api/v1/users/me"
done
echo ""

echo "--- v2 (current) ---"
for i in $(seq 1 50); do
  curl -s -o /dev/null -w "%{http_code} " \
    -H "Authorization: Bearer $TOKEN" \
    "https://target.com/api/v2/users/me"
done
echo ""

# Compare authentication requirements
curl -s -o /dev/null -w "v1 no auth: %{http_code}\n" \
  "https://target.com/api/v1/users"
curl -s -o /dev/null -w "v2 no auth: %{http_code}\n" \
  "https://target.com/api/v2/users"

# Compare response fields (data exposure in old versions)
echo "=== v1 fields ==="
curl -s -H "Authorization: Bearer $TOKEN" \
  https://target.com/api/v1/users/me | jq 'keys'
echo "=== v2 fields ==="
curl -s -H "Authorization: Bearer $TOKEN" \
  https://target.com/api/v2/users/me | jq 'keys'
```

### Step 3: Test Version Rollback Attacks

```bash
# Test BOLA on old version where fix may not be backported
curl -s -H "Authorization: Bearer $USER_B_TOKEN" \
  https://target.com/api/v1/users/USER_A_ID | jq .

# Test mass assignment on old version
curl -s -X PUT -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role":"admin"}' \
  https://target.com/api/v1/users/me

# Test injection on old version
curl -s -H "Authorization: Bearer $TOKEN" \
  "https://target.com/api/v1/search?q=test'+OR+1=1--"
```

### Step 4: Scan for Shadow APIs

```bash
# Fuzz for undocumented endpoints on old versions
ffuf -u "https://target.com/api/v1/FUZZ" \
  -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt \
  -H "Authorization: Bearer $TOKEN" \
  -mc 200,201,204,301,302,403 -o shadow_api.json -of json

# Check for internal/debug endpoints on old versions
INTERNAL=(
  "/api/v1/debug" "/api/v1/internal" "/api/v1/test"
  "/api/v1/swagger" "/api/v1/docs" "/api/v1/graphql"
  "/api/v1/health" "/api/v1/metrics" "/api/v1/status"
)
for EP in "${INTERNAL[@]}"; do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
    "https://target.com$EP")
  [ "$STATUS" != "404" ] && echo "$EP: HTTP $STATUS"
done
```

## Detection Opportunities

| Signal | Source | Description |
|--------|--------|-------------|
| Deprecated version access | API gateway | Requests to sunset API versions |
| Version header tampering | WAF | Unusual version values in requests |
| Cross-version probing | Metrics | Same client testing multiple versions |
| Shadow API discovery | Network logs | Requests to undocumented endpoints |

```yaml
title: Deprecated API Version Access
id: f2a3b4c5-d6e7-8901-fabc-012345678901
status: experimental
description: Detects access to deprecated API versions that should be decommissioned
logsource:
  category: webserver
detection:
  selection:
    cs-uri-stem|contains:
      - '/api/v1/'
      - '/api-v1/'
  filter:
    cs-uri-stem|contains: '/api/v1/health'
  condition: selection and not filter
falsepositives:
  - Legacy clients that have not migrated to current version
level: medium
tags:
  - attack.t1190
  - attack.initial_access
```

## Verification

- [ ] All API versions enumerated and inventoried
- [ ] Deprecated versions return 410 Gone or are fully decommissioned
- [ ] Security controls consistent across all active versions
- [ ] Old versions do not expose more data than current
- [ ] Rate limiting enforced on all versions
- [ ] Shadow APIs identified and secured or removed

## References

- [OWASP API9:2023 — Improper Inventory Management](https://owasp.org/API-Security/editions/2023/en/0xa9-improper-inventory-management/)
- [API Versioning Best Practices](https://restfulapi.net/versioning/)
- [MITRE ATT&CK T1190](https://attack.mitre.org/techniques/T1190/)
