Shadow API - Undokumentierte und unkontrollierte API-Endpunkte
Shadow APIs are undocumented, forgotten, or unmanaged API endpoints that run in production without the security team’s knowledge. They arise from legacy systems, rapid development cycles, or shadow IT. Security risks include: no authentication, missing rate limits, and unpatched vulnerabilities. Detection is achieved through API discovery tools, traffic analysis, and API gateways.
Shadow APIs are API endpoints that are active in production but are not officially documented, registered, or monitored by the security team. They arise from legacy systems, rapid development cycles without API governance, or shadow IT initiatives. Since they operate outside normal security processes, they are often unsecured and represent a significant attack surface.
Origin of Shadow APIs
Typical Sources
Legacy Systems:
- Old API version (v1, v2) remains active after v3 is introduced
- "Still used by an old client" → never shut down
- Undocumented in the OpenAPI spec, but active in production code
Development Shortcuts:
- Developer creates debug endpoint (
/api/debug/user/{id}) - Accidentally goes into production (no feature flags)
- Not recorded as an asset in the CI/CD pipeline
Microservices Chaos:
- Team A deploys its own auth microservice
- Not registered with the central API gateway
- Accessible directly via service discovery
Third-party integrations:
- SaaS provider provides API callback endpoint
- Endpoint runs on company infrastructure
- Not included in internal API inventory
Mobile app backend:
- Old app version (1.x) communicates with old backend
- App no longer in the store → Backend "forgotten"
- API continues to run silently, without patches
Shadow API Types
| Type | Description |
|---|---|
| Zombie APIs | Old versions never shut down |
| Undocumented | Exists, but not in Swagger/OpenAPI |
| Internal APIs | Internal microservice APIs accessible from outside |
| Partner APIs | B2B endpoints without the same security level |
| Test APIs | Dev/staging endpoints in production |
Security Risks
1. Lack of Authentication
Normal APIs use OAuth 2.0, API keys, or JWT. Shadow APIs are often completely unsecured based on the principle that "nobody knows about them":
GET /api/internal/users/list → 200 OK + complete user list
(no Authorization header required!)
2. No Rate Limits
An API gateway typically limits requests to 100 per minute per API key. Shadow APIs completely bypass the gateway—unlimited access, data exfiltration possible through enumeration.
3. Unpatched Vulnerabilities
Legacy endpoints run on old Node.js versions with known CVEs. Since they are not in the inventory, there is no patch management. Common vulnerabilities: OWASP API2:2023 – Broken Authentication, SQL injection in old query parameters.
4. Missing validation
Newer APIs use input validation and schema enforcement. Shadow APIs have no schema – mass assignment is possible. BOLA/IDOR: /api/v1/order/{id} without access checks.
5. No Monitoring Coverage
SIEM, WAF, and DAST only cover known endpoints. Requests against shadow APIs generate no alerts and no logs. Attackers can operate undetected.
Attack Example - API Enumeration
# Attacker scans for old API versions:
for version in v1 v2 v3 v4 v5 api old legacy beta; do
curl -s "https://target.com/api/${version}/users" \
-o /dev/null -w "%{http_code} /api/${version}/users\n"
done
Typical result:
/api/v2/users: 200 OK- Shadow API found!/api/v3/users: 401 Unauthorized- production API, secured/api/old/admin: 200 OK- critical!
API Discovery and Inventory
Detecting Shadow APIs
1. Traffic Analysis (Passive):
# Extract all API calls from proxy logs:
cat /var/log/nginx/access.log | \
grep -E "^[0-9.]+ .+ \"(GET|POST|PUT|DELETE|PATCH)" | \
awk '{print $7}' | \
grep "^/api" | \
sort -u > api-endpoints-found.txt
# Compare with documented endpoints:
diff api-endpoints-found.txt api-documented.txt
2. DAST Discovery with Postman/Swagger Parser:
# Crawl Swagger/OpenAPI:
curl -s "https://target.com/swagger.json" | \
jq -r '.paths | keys[]'
# Note: Shadow APIs are not listed in Swagger!
3. JavaScript Source Analysis:
# Analyze JS bundles for API calls:
curl -s "https://target.com/app.bundle.js" | \
grep -oE '(api|/v[0-9]+)/[a-z/{}]+' | sort -u
# Also: Source maps if publicly accessible!
4. API Discovery Tools:
- Postman API Network (publicly leaked collections)
- 42Crunch API Discovery
- Salt Security API Discovery
- Traceable AI
5. Kubernetes Service Discovery:
# List all services in the cluster:
kubectl get services --all-namespaces | grep -v kube-system
# ClusterIP services: internally accessible – from which network segment?
6. Cloud Resources:
# AWS API Gateway - all APIs:
aws apigateway get-rest-apis --query 'items[*].[name,id]'
# Unknown APIs in your own account!
Prevention and API Governance
API-First Development
- Every endpoint is first defined in the OpenAPI spec
- Code generation from the spec (no manual writing)
- CI/CD: API spec must be committed before deployment
API Gateway as a Requirement
All requests must go through the API Gateway. Direct access to backend services is blocked. Unregistered paths: 404 (not 200!).
Kong Gateway - Catch-All for unregistered paths:
plugins:
- name: route-by-header
config:
rules:
- header: X-API-Version
upstream_url: http://backend-v3
# Default → 404 for everything not registered
Automate API Inventory
Every new endpoint requires a PR + spec update + registry entry (in Backstage or SwaggerHub).
Backstage API Component (catalog-info.yaml):
apiVersion: backstage.io/v1alpha1
kind: API
metadata:
name: user-service-v3
annotations:
backstage.io/techdocs-ref: dir:.
spec:
type: openapi
definition:
$text: ./openapi.yaml
Deprecation Process
- API Version: Set
X-Deprecation-Dateheader - Sunset Date: 6 months' advance notice
- Traffic Monitoring: Which clients are still using the old version?
- Hard removal after sunset date (no exceptions!)
Deprecation Headers in the Response:
Sunset: Sat, 31 Dec 2026 23:59:59 GMT
Deprecation: true
Link: <https: api.example.com="" v3="" users="">; rel="successor-version"
API Security Testing
Finding Shadow APIs in a Penetration Test
Automated Discovery:
# feroxbuster for API endpoint discovery:
feroxbuster -u https://api.target.com \
-w /usr/share/wordlists/api-endpoints.txt \
-x json \
--filter-status 404,403 \
--threads 50
# kiterunner (API-specific):
kr scan https://api.target.com \
-w routes-large.kite \
--fail-status-codes 404,403,400
# Assetnote wordlists for APIs:
# https://wordlists.assetnote.io/
# best-dns-wordlist.txt for subdomains
# aspx-large.txt, jsp-large.txt for endpoints
Testing versioning:
# Test all API versions:
for v in v1 v2 v3 v4 v5 v6 v7 v8 v9 v10; do
status=$(curl -s -o /dev/null -w "%{http_code}" \
"https://api.target.com/${v}/users")
echo "${v}: ${status}"
done
JavaScript analysis:
# Extract all API endpoints from JS:
node -e "
const fs = require('fs');
const content = fs.readFileSync('app.bundle.js', 'utf8');
const matches = content.match(/['\"]\/api\/[^'\"]+['\"][^;]*/g);
console.log([...new Set(matches)].join('\n'));
"
```</https:>