📋 What Is It?
Improper Inventory Management occurs when organizations lack visibility into their API landscape. This includes outdated API versions, exposed debug endpoints, unpatched systems, and lack of documentation. Attackers exploit old, forgotten, or poorly documented APIs that organizations don't even know exist.
API09
OWASP Rank
Shadow
APIs at Risk
Old
Versions Exposed
⚠️ Common Exploits
- Old API Versions: /api/v1 still accessible with known vulnerabilities
- Shadow APIs: Undocumented endpoints deployed without security review
- Zombie APIs: Forgotten APIs still running and accessible
- Debug Endpoints: /debug, /test left in production
- Unpatched APIs: Old versions missing critical security updates
- Beta/Staging Exposed: Non-production environments publicly accessible
🔴 Attack Flow
1. Attacker discovers current API: /api/v3
↓
2. Tests old versions: /api/v1, /api/v2
↓
3. Finds v1 still active with vulnerabilities
↓
4. Exploits known BOLA in v1
↓
5. BREACH: Access to all user data via old API!
↓
2. Tests old versions: /api/v1, /api/v2
↓
3. Finds v1 still active with vulnerabilities
↓
4. Exploits known BOLA in v1
↓
5. BREACH: Access to all user data via old API!
❌ Vulnerable Configuration
// Bad: Multiple API versions without sunset
// All versions accessible simultaneously:
/api/v1/users ← Deployed 2019, has BOLA vulnerability
/api/v2/users ← Deployed 2020, missing auth on some endpoints
/api/v3/users ← Current version (2023), secure
// Bad: No inventory tracking
// Routes.py - Teams don't know what's deployed
@app.route('/api/users')
@app.route('/api/v1/users')
@app.route('/api/v2/users')
@app.route('/api/internal/users') ← Shadow API!
@app.route('/api/test/users') ← Test endpoint in prod!
// Bad: No documentation
// Endpoints exist but not documented:
GET /api/users ← Documented
POST /api/users ← Documented
GET /api/admin/export ← NOT documented (shadow API)
GET /api/debug/dump ← NOT documented (dangerous!)
// Bad: Exposed non-production environments
https://api.example.com ← Production
https://staging-api.example.com ← Publicly accessible!
https://dev-api.example.com ← Publicly accessible!
https://test-api.example.com ← Publicly accessible!
✅ Secure Management
// Good: API versioning with sunset policy
// api_versions.py
SUPPORTED_VERSIONS = {
'v3': {'active': True, 'sunset_date': None},
'v2': {'active': True, 'sunset_date': '2024-12-31'},
'v1': {'active': False, 'deprecated': True} ← Disabled!
}
@app.before_request
def check_api_version():
version = extract_version(request.path)
if version not in SUPPORTED_VERSIONS:
abort(404)
if not SUPPORTED_VERSIONS[version].get('active'):
return jsonify({
'error': 'API version deprecated',
'message': 'Please upgrade to v3'
}), 410 # Gone
# Add sunset header for soon-to-be-deprecated versions
sunset = SUPPORTED_VERSIONS[version].get('sunset_date')
if sunset:
response.headers['Sunset'] = sunset
response.headers['Deprecation'] = 'true'
// Good: API inventory management
// api_catalog.yaml - Single source of truth
apis:
- name: User API
version: v3
endpoint: /api/v3/users
status: active
owner: team-backend
authentication: JWT
last_security_review: 2024-01-15
- name: User API v2
version: v2
endpoint: /api/v2/users
status: deprecating
sunset_date: 2024-12-31
owner: team-backend
- name: User API v1
version: v1
endpoint: /api/v1/users
status: disabled
disabled_date: 2023-06-01
// Good: Environment restrictions
// Nginx configuration
server {
server_name staging-api.example.com;
# Restrict to internal IPs only
allow 10.0.0.0/8;
allow 192.168.0.0/16;
deny all;
location / {
proxy_pass http://staging-backend;
}
}
// Good: Automated API discovery
def scan_registered_routes():
"""Scan and catalog all registered API routes"""
routes = []
for rule in app.url_map.iter_rules():
routes.append({
'endpoint': rule.rule,
'methods': list(rule.methods),
'function': rule.endpoint
})
# Compare with documented APIs
undocumented = find_undocumented_routes(routes)
if undocumented:
logger.warning(f"Shadow APIs detected: {undocumented}")
return routes
✓ Prevention Checklist
- Maintain complete API inventory/catalog
- Document all API endpoints and versions
- Implement API versioning with sunset policy
- Disable/remove old API versions
- Regular API discovery scans
- Restrict non-production environments
- Remove debug/test endpoints from production
- Track API owners and responsibilities
- Regular security reviews per API
- Monitor for shadow APIs
- Use API gateways for centralized management
- Implement API lifecycle management
🔍 Detection & Tools
Discovery Tools:
Postman
Swagger
OpenAPI
APIClarity
Traceable AI
Noname Security
Management Tools:
Kong
Apigee
AWS API Gateway
Azure API Management
MuleSoft
How to Test:
- Enumerate API versions (v1, v2, v3, etc.)
- Test common debug paths (/debug, /test, /admin)
- Check for staging/dev subdomains
- Compare documented vs actual endpoints
- Scan for orphaned endpoints
- Review DNS records for forgotten APIs
🌍 Real-World Breaches
- T-Mobile (2021): Old API version with vulnerabilities still accessible
- USPS (2018): API endpoint existed for years without security review
- Facebook (2019): Deprecated API still accessible, exposing user data
- Venmo (2018): Old API version leaked transaction data
- Panera Bread (2018): Forgotten API exposed 37M customer records
📌 Quick Tips
- DO NOT leave old API versions running
- DO NOT expose staging/dev environments
- DO NOT deploy undocumented APIs
- DO maintain complete API inventory
- DO implement API versioning sunset
- DO regularly scan for shadow APIs
- DO use API gateway for management
📜 Compliance
Related Standards:
- PCI-DSS Requirement 2.2.5 - Inventory
- NIST 800-53 CM-8 - System Inventory
- ISO 27001 A.8.1.1 - Asset Inventory
- SOC 2 CC7.1
- GDPR Art. 30 - Records of Processing