Debug and testing modes enabled

Debug or testing mode enabled in a production Python web application

Description

Debug modes in frameworks such as Django, Flask and FastAPI provide detailed errors during development. In production, they may include stack traces, source excerpts, local variables or configuration values in responses.

Flask's TESTING setting is separate from debug mode. It enables testing behavior in extensions and implicitly enables exception propagation unless PROPAGATE_EXCEPTIONS is set separately. TESTING=True does not itself turn on Flask's interactive debugger, but it can change normal production error handling and let testing behavior affect real requests.

Potential impact

  • Internal information exposure: Django's detailed error pages and FastAPI's debug tracebacks may disclose source locations, settings and request-processing details.
  • Remote code execution: An exposed Flask/Werkzeug interactive debugger can execute Python code from a browser. Its PIN must not be treated as a security control.
  • Changed error and extension behavior: Flask testing mode may propagate exceptions instead of passing them to application error handlers, and extensions may enable test-specific behavior.

Remediation

  • Keep Django DEBUG, Flask DEBUG and TESTING, and FastAPI debug set to the boolean False in production.
  • Separate development, testing and production configuration, and automatically verify the effective settings before deployment.
  • Use a production server instead of the framework's development server or interactive debugger. Configure generic error responses, server-side logging and alerts.
  • Do not pass environment variable strings directly to boolean arguments. os.getenv("DEBUG", "False") returns a string, and the nonempty string "False" is truthy in Python. Parse environment settings into booleans in a typed configuration layer first.

Keep settings needed for development or testing separate from production, and check the final values used by the deployment.

Examples

Django

Before

python
# settings/production.py
DEBUG = True

After

python
# settings/production.py
DEBUG = False

Flask debug mode

Before

python
from flask import Flask

app = Flask(__name__)
app.run(debug=True)

After

python
from flask import Flask

app = Flask(__name__)
app.config["DEBUG"] = False

# Run with a production WSGI server, not the Flask development server.

Flask testing mode

Before

python
from flask import Flask

app = Flask(__name__)
app.config.update(TESTING=True)
# app.testing = True enables the same setting.

After

python
from flask import Flask

app = Flask(__name__)
app.config.update(TESTING=False)

FastAPI

Before

python
from fastapi import FastAPI

app = FastAPI(debug=True)

After

python
from fastapi import FastAPI

app = FastAPI(debug=False)

Explanation:

  • Before: Enables detailed errors or test-specific behavior in production.
  • After: Disables these features with the actual boolean False in production configuration.

References