Security implications of
DEBUG=true in Django. Learnings from an ethical hacker's perspective. How to escalate it to higher severity 👇 (from low/medium to high/critical)
What is a debug mode in Django?
Debug mode in Django is a setting (
DEBUG=True) that helps in the application development phase by providing detailed error pages when something goes wrong, but It's a security risk in a production environment and should be turned off 🥸
Security implications of
DEBUG=true in Django app
An attacker will be able to:
- Extract all endpoints available on the server
- Leak secrets and credentials (most of the time)
- Escalate it to RCE, SSRF, SQLi
The detailed error page with stack trace + information about available endpoints is a superpower for ethical hackers. I used it several times and escalated it to SSRFs, RCEs, and credential leaks.
How to detect Debug mode in the Django app at scale?
You can use the module on the Vidoc platform:)
How to use this module:
- Create a free account on the Vidoc platform
- Start Recon on some domain and wait for the Recon to finish
- Go to Module and click "Execute Module"
Let's look at extracting the list of endpoints first!
Listing endpoints in Django app
To do that we need to request an endpoint that does not exist in the application, for example:
- /doesnotexist - /api/doesnotexist
When you open the page with the endpoint that does not exist you will be able to see all other endpoints! You can try going even deeper by looking at returned endpoints and adding
doesnotexist to them.
In our case:
- /api/v1/doesnotexist - /admin/doesnotexist
If you are lucky, the errors will return more endpoints:)
Leaking credentials in Django app
This is all about triggering
RuntimeError. When the server encounters a "severe" error it will print the whole stack trace that will contain the settings of the server and potential secrets.
How to trigger RuntimeError in Django app?
1. Use the list of endpoints and try making a request with the wrong request method, wrong params, or wrong auth tokens
2. Make a POST request to
When you trigger the
RuntimeError you should see a red page with a stack trace!
Where to find exposed secrets?
- They can be found in the Settings section (at the bottom of the error page).
- In newer versions of Django, secrets can also be leaked through "Local vars" of the stack trace (Django does not sanitize it)
Escalating to SQLi, SSRF, RCE
With the stack trace, you can gain insights into how the service works - you can leak parts of the code and use it to your advantage. You can check which endpoints are available without any for of authentication and use them for further research.
- Check which endpoints are avaliable without auth (if you have authentication for the service you can skip this step)
- Try sending requests to those endpoints with malformed requests - with SSRF, SQLi, RCE, or any other payloads
- If there is any indication that the endpoint might be vulnerable to SSRF, SQLi, or RCE - go deeper and use the stack trace to your advantage:)