Debug mode enabled in production
CWE-489CWE-215OWASP A05:2021Updated September 4, 20264 min read
An application running in debug mode in production reveals its internal structure on every error: file paths, configuration, environment variables and sometimes the queries executed. Some development tools even offer a console that runs code. That is no longer an information leak but a direct route to the server.
Debug mode is built to reveal as much as possible: that is precisely its purpose during development. If that setting stays on in production, it does that job just as well, only for a different audience. This article explains what becomes visible and why some development tools do not merely leak information but grant direct access.
What is debug mode?
Debug mode is the setting in which a framework or application shows as much information as possible about what is happening internally. On an error, no tidy message appears but a full explanation: the stack trace with file paths and line numbers, the values of variables, the database queries executed, the loaded configuration and sometimes the complete environment variables.
Alongside that there are development tools that run permanently: profilers, debug bars, error consoles. Those show not only what went wrong but everything that happened, including on a successful request. They are designed for an environment where only the developer has access.
The contrast with the intended situation is stark. In production an error should produce a neutral message with a reference number. In debug mode that same error produces a detailed description of your system, to whoever asks for it.
What does debug mode make visible?
Vulnerable:
// In the configuration file of the production environment
APP_ENV=production
APP_DEBUG=true
One value set wrongly. A request that triggers an error now produces a page containing, among other things:
UnexpectedValueException in /var/www/portal/src/Invoice/Repository.php:88
Environment variables:
DB_HOST=10.0.4.12
DB_USERNAME=portal_prod
DB_PASSWORD=Xk29!vRp2mQz
MAIL_PASSWORD=cf83e1357eefb8bd
APP_KEY=base64:9c2f81ad4e7b3f5c...
This is no longer an information leak in the usual sense. The database password is on screen; if the database is reachable from outside, that is direct access to all the data. The application key is more serious still: with it, session cookies can be forged and, in frameworks that store objects in cookies, that can lead to code execution on the server.
With a profiler something else comes on top. Some tools offer a built-in console or a route that evaluates arbitrary expressions. If that is reachable without authentication, the step from information leak to full takeover has already been taken.
Safe:
APP_ENV=production
APP_DEBUG=false
// The application refuses to start in an unsafe combination
if (env('APP_ENV') === 'production' && env('APP_DEBUG') === true) {
throw new RuntimeException('Debug mode is not permitted in production.');
}
The second measure is the important one. A setting that is only correct because someone remembered it will sooner or later be wrong. An application that refuses to start in an unsafe combination makes the mistake impossible rather than unlikely. Also remove development packages entirely from the production build, so a profiler is not merely switched off but absent.
What is the impact of debug mode in production?
The severity is high to critical, which sets this finding apart from ordinary information leaks. The reason is that the exposed information usually contains secrets rather than only structural details.
The most serious route runs through the application key. In many frameworks, sessions and cookies are signed or encrypted with it. Whoever holds the key can manufacture a valid session for any user, including administrators, without ever needing to know a password. In frameworks that store serialised objects in cookies, that can extend to executing code on the server.
Beyond that, database credentials, keys for payment and email services, and internal network addresses lie open. Those last are valuable for the next step: they tell an attacker which systems run behind the application and where to direct their attention.
What makes this finding particularly awkward is that finding it requires no skill. There is large-scale automated searching for applications with an active debug mode, precisely because the yield is so high.
How do you detect debug mode in production?
A tester deliberately triggers errors, an invalid parameter value, a non-existent route, a malformed request, and assesses whether the response shows more than a neutral message. A stack trace with file paths is the clearest signal.
They also look for the known paths of development tools: profiler routes, debug bars, status pages and routes exposing the configuration or loaded modules. Those often sit at a predictable address and are quickly found with a targeted check. Subtler indications get attention too: a response header revealing the debug state, an HTML comment with the execution time, or an error page that appears only in development mode. Acceptance and test environments receive particular attention, because they are often reachable from the internet and nearly always run in debug mode with data resembling production. AssistSec covers those environments as standard during reconnaissance, because in practice they turn out to be an entry point more often than production itself.
How do you prevent debug mode in production?
- Switch debug mode off explicitly in every environment reachable from the internet.
- Make the application refuse to start when debug mode and production are set together.
- Remove profilers and other development packages entirely from the production build.
- Keep secrets out of configuration that can be shown on an error, for instance in a key vault.
- Rotate all secrets when debug mode has unintentionally been on.
- Shield test and acceptance environments with network restrictions or authentication.
- Use structured logging with reference numbers instead of information in the response.
- Check the setting automatically on every deployment, so a manual change does not persist.
- Block known debug and profiler paths in your web server as a safety net.
Sources
Frequently asked questions
How does debug mode end up in production?
Usually because an environment variable is unset and the default is on, or because a setting was turned on temporarily while resolving an incident and then stayed. Both are human; the answer is that the production environment enforces the setting itself rather than relying on someone remembering.
Is a profiler just as bad?
Often worse. A profiler shows not only the error but the whole execution: every query, the session contents, the configuration and sometimes requests from other users. Some tools also include a console that runs code.
Can I limit debug mode to my own IP address?
That is better than nothing, but it remains a risk you do not have to take. IP restrictions can be bypassed when the application derives the address from a header, and the setting stays on until someone remembers it. Prefer a separate environment with the same structure.
What if I need information about a production incident?
Use structured logging and an error reporting system with a reference number per incident. You get the same information, but in your own environment rather than in the response to the visitor.
Related articles
- VulnerabilitiesCWE-1188A05:2021Default web server files reachableSample pages, admin consoles and installation files left after setup reveal your platform and are sometimes directly abusable.
- VulnerabilitiesCWE-200A01:2021Information disclosureInformation disclosure explained: how stack traces, .git directories, source maps and over-sharing API responses leak data, and how to stop it.
- VulnerabilitiesCWE-16A05:2021Security misconfigurationSecurity misconfiguration explained: how default passwords, debug modes and open cloud buckets let attackers in, and how to harden your systems.
- VulnerabilitiesCWE-527A05:2021Source code publicly accessibleA published .git folder or backup file gives away your entire source code, including passwords from old commits. Learn how to prevent that.
- VulnerabilitiesCWE-209A05:2021Detailed error messagesStack traces and database errors reveal your technology, paths and queries. Learn what an attacker takes from them and how to handle errors.