
Misconfigurations are often the weakest link in an otherwise secure environment. One of the most dangerous yet easily overlooked misconfigurations in Django is leaving DEBUG=True
in a production environment. From an attacker’s perspective, this is a goldmine for reconnaissance and exploitation. This article explores how attackers can exploit this setting and the top five valuable data types they can retrieve from a vulnerable Django application.
What Does DEBUG=True Do in Django?
In Django, the DEBUG
setting controls whether debug information, including error stack traces and detailed request information, is shown when an error occurs. With DEBUG=True
, Django outputs a verbose error page containing sensitive information to aid developers during the development process.
From an Attacker’s Point of View:
When an attacker finds a Django site running with DEBUG=True
, it’s as though the application is openly offering detailed internal information to help them craft their attack. These verbose error messages contain everything from the server’s environment variables to installed middleware and even potential entry points for attack.
How Attackers Identify Django Sites with DEBUG=True
Scanning the Web for Vulnerable Sites
Attackers use automated tools like Shodan, FOFA, and Censys to scour the web for Django applications. These tools allow attackers to search for specific error messages and patterns associated with DEBUG=True
.
Practical Method:
- FOFA Query:
"DEBUG=True" && "Django" && "RuntimeError"

These search engines scan the internet for open ports and services and then analyze the HTTP responses to see if they contain known Django debug patterns. With these search results, attackers can compile a list of vulnerable websites running Django with DEBUG=True
.
Data Leaked via Django Debug Pages
When DEBUG=True
is set, attackers can harvest valuable information directly from the debug pages.
Practical Data Retrieval:
Full Stack Trace:
- The stack trace provides insight into how the code executes, where errors occur, and potentially exposed variables in requests and responses.
- Example:
Traceback (most recent call last): File "/path/to/your/project/views.py"...
Practical Use: Attackers can identify code execution paths and look for points where input is processed, enabling targeted attacks like SQL injection or file inclusion exploits.

Request and Response Data:
- Attackers gain insight into cookies, CSRF tokens, and headers from both the request and the response.
- Practical Use: Using this information, attackers can perform session hijacking, steal CSRF tokens, or craft more effective social engineering attacks.
Request Headers: { 'Cookie': 'sessionid=abcd1234; csrftoken=efgh5678...',
'User-Agent': 'Mozilla/5.0...' }
Installed Applications and Middleware:
Installed apps: ['django.contrib.admin', 'myapp', 'rest_framework'...]
Practical Use: By analyzing installed apps and middleware, attackers can identify vulnerable third-party libraries or unpatched components.
Database and File Paths:
- While the database password might not be directly shown, other details like the database engine, file paths, and schema are often exposed.
- Practical Use: Attackers could exploit known vulnerabilities in the database system or file system, or even find files that expose further credentials or sensitive data.
4. Practical Methods for Exploiting a Django DEBUG=True Configuration
Leveraging the Stack Trace
Once a vulnerable site is identified, the next step is to extract as much information as possible from the stack trace. This includes sensitive details like:
- File paths:
File "/var/www/myapp/views.py" in render
The file path gives an attacker clues about the structure of the server and potential locations of sensitive files (config files, logs, etc.).
Seeing which functions and methods are being called and how they handle input can expose SQL injection points, XSS vulnerabilities, or logic flaws.
CSRF Token Abuse
If an attacker can retrieve the CSRF token, they can carry out Cross-Site Request Forgery attacks. If the token is tied to an active session, an attacker can:
- Perform unauthorized actions on behalf of a user (e.g., making purchases or transferring funds).
- Hijack user sessions if combined with a stolen session cookie.

Database Exploitation
Attackers can retrieve partial database configurations (such as the database type and schema) from debug pages and combine them with other known vulnerabilities to:
- Execute SQL injections.
- Bypass authentication or escalate privileges by understanding how the database queries are processed.

The Top 5 Valuable Data Attackers Can Retrieve from DEBUG=True
SECRET_KEY: While Django tries to hide this in debug output, it is sometimes retrievable through indirect methods or misconfigurations in related files. With the SECRET_KEY
, attackers can:
- Generate forged session tokens.
- Bypass authentication mechanisms.
Database Credentials: Exposure of database engines or schemas can lead to SQL injection or direct access to the database if credentials are mismanaged.
CSRF Tokens: Once CSRF tokens are exposed, attackers can manipulate user sessions to perform malicious actions or hijack sessions entirely.
Session Cookies: If session cookies are exposed in the request/response data, attackers can steal active user sessions and impersonate legitimate users.
Installed Middleware and Apps: By knowing what middleware and third-party applications are installed, attackers can exploit known vulnerabilities in these packages, especially if they are outdated.
How Developers Can Prevent These Attacks
As you can see, leaving DEBUG=True
in production provides attackers with a wealth of sensitive information. To prevent such issues:
- Always set
DEBUG=False
in production. - Use environment-specific settings to ensure no sensitive data is leaked in error messages.
- Implement robust logging practices that hide sensitive data but still provide useful information for debugging.
For Django developers, securing applications against misconfigurations like this is crucial to safeguarding against exploitation.