Fix Improper Error Handling in Flask
Leaking stack traces is a gift to any pentester. In Flask, default error responses often dump the entire execution context, revealing library versions, file paths, and database schemas. This Information Exposure (CWE-209) simplifies exploit development. We harden this by centralizing error logic and stripping internal metadata from responses.
The Vulnerable Pattern
from flask import Flask, requestapp = Flask(name)
@app.route(‘/user’) def get_user(): try: # Malicious input could trigger a traceback here user_id = request.args.get(‘id’) return f’User Data for {int(user_id)}’ except Exception as e: # VULNERABLE: Directly returning the exception string to the client # Also, running with debug=True enables the interactive debugger (RCE risk) return str(e), 500
if name == ‘main’: app.run(debug=True)
The Secure Implementation
The secure implementation relies on three security controls: 1. Global Error Handler: Using @app.errorhandler(Exception) ensures that no unhandled exception escapes as a raw traceback. 2. Sanitized Responses: We return generic JSON messages to the user while logging the actual 'dirty' error details to a secure server-side file. 3. Debug Suppression: Setting debug=False is critical; the Werkzeug debugger allows arbitrary code execution via the browser if it's left active on a public-facing instance.
import logging from flask import Flask, jsonify from werkzeug.exceptions import HTTPExceptionapp = Flask(name)
Configure server-side logging for internal debugging
logging.basicConfig(level=logging.INFO)
@app.errorhandler(Exception) def handle_exception(e): # Log the full stack trace internally app.logger.error(f’Unhandled Exception: {str(e)}’, exc_info=True)
# If it's a known HTTP error, keep its status code if isinstance(e, HTTPException): return jsonify({'error': e.description}), e.code # Return a generic message for everything else return jsonify({'error': 'An internal server error occurred', 'ref': 'check_logs'}), 500@app.route(‘/user’) def get_user(): user_id = int(request.args.get(‘id’)) return jsonify({‘id’: user_id})
if name == ‘main’: # SECURE: debug=False in production app.run(debug=False)
Your Flask API
might be exposed to Improper Error Handling
74% of Flask 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.