Fix Shadow API Exposure in Bottle
Shadow APIs are undocumented, unmanaged endpoints lurking in your production environment, often bypassing security controls and monitoring. In Bottle, these typically arise from legacy routes, accidental global registrations, or debug handlers left in the code. To a researcher, these are goldmines; to a dev, they are high-risk liabilities.
The Vulnerable Pattern
from bottle import route, run, requestDocumented API
@route(‘/api/v1/status’) def status(): return {‘status’: ‘online’}
SHADOW API: Leftover debug endpoint, undocumented and unauthenticated
@route(‘/debug/internal/vars’) def dump_env(): import os return dict(os.environ)
Catch-all route can also hide shadow behavior
@route(‘/path:path’) def catchall(path): return f’Path {path} is handled genericly’
run(host=‘0.0.0.0’, port=8080)
The Secure Implementation
Fixing shadow exposure requires three pillars: Isolation, Documentation, and Gating. 1) Abandon the global @route decorator; use explicit Bottle() instances to prevent accidental route pollution. 2) Implement Environment Gating to ensure debug or administrative routes cannot be registered in production builds. 3) Integrate an OpenAPI/Swagger generator (e.g., bottle-swagger) to force a 'Doc-or-Die' policy where undocumented routes are caught during CI/CD. 4) Bind to localhost or use a reverse proxy to prevent direct exposure of the application port to the public internet, ensuring all traffic passes through a controlled WAF/Gateway.
from bottle import Bottle, request, response, abort import osapp = Bottle()
def validate_env(): if os.getenv(‘APP_ENV’) != ‘development’: return False return True
Explicit route registration on a specific app instance
@app.get(‘/api/v1/status’) def status(): return {‘status’: ‘online’}
Secure approach: Environment gating and explicit removal
if validate_env(): @app.get(‘/debug/internal/vars’) def dump_env(): return {‘mode’: ‘debug_active’}
Enforce strict 404s and logging for unknown paths to detect discovery scans
@app.error(404) def error404(error): # Log this attempt for SIEM analysis return ‘Resource not found’
if name == ‘main’: app.run(host=‘127.0.0.1’, port=8080, server=‘waitress’)
Your Bottle API
might be exposed to Shadow API Exposure
74% of Bottle apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.