Leftover Debug Code
The gate was the bug. One typo left the debug route open.
What Is Leftover Debug Code?
The flaw here is not in the feature but in the switch meant to turn it off. A debug route guards itself with a misspelled environment variable, the comparison becomes undefined !== 'production' , and the route answers in production. You'll sweep debug paths until /api/_debug/env returns the database password, the JWT signing secret and live cloud keys, then forge an admin token with that secret. The fix rotates every leaked credential and excludes the route from the production bundle at build time.
What You'll Learn in Leftover Debug Code
- Recognize debug-route exposure as a security-misconfiguration failure mode, the gate is the bug, not the logic the gate protects
- Understand that runtime env-var gates fail silently on typos (<code>process.env.UNDEFINED</code> returns undefined, no error), so positive allow-lists with explicit equality are safer than negative deny-lists
- Apply the immediate fix (rotate every leaked credential, flip the gate to an explicit allow-list with the correct env-var name) and the systemic fix (build-time exclusion via DefinePlugin / esbuild --define / conditional require)
- Audit every debug, status, health, metrics, and admin-internal endpoint for response content that includes secrets, internal IPs, dependency versions, or stack traces
- Internalize: routes that should not exist in production should be absent from the production bundle, not present-but-gated
Leftover Debug Code — Training Steps
-
Size up the target
Bob is a malicious actor. He makes his living pulling data out of companies that left something exposed, then selling it or using it to get at their money. Today his target is Vessura, a procurement platform other businesses run on. He starts where anyone would, on the public site, sizing the company up before he looks for a way in.
-
Map what is exposed
Nothing on the public site is unusual: a login, a vendor directory, a support page. But apps ship with more than their front door. Developer scaffolding left in a build stays reachable by anyone who goes looking, so Bob maps every path the portal's API actually answers.
-
Hit the debug route
Bob rebuilds the request the scan flagged. He points the API Tester at the debug path and sends a plain GET, no login and no token, to see what it hands back.
-
Every secret at once
The response is not an error page. It is the entire process environment of a production server, handed to a request that carried no login.
-
Forge an admin token
The dump handed Bob the JWT_SECRET , the key the app uses to sign every session token. Back in the same terminal, he mints his own token, stamps the role as admin, and the server will accept it as a genuine login.
-
Walk in as admin
Now Bob uses the token. He calls the internal vendor API, a page meant only for signed-in admins, and carries the forged token in an Authorization header so the server treats him as one. The terminal on the left still holds the token he just minted.
-
The ledger is open
The server trusted the token and answered. Bob is now reading the internal vendor ledger from a public API, with no account of his own.
-
Knowledge check
You just watched a single leftover path hand over every secret and then an admin session. Lock in why.
-
The DLP alert lands
You own Vessura's procurement portal. Overnight, outbound data-loss monitoring tripped on a response that carried live secrets off the server. Security operations has emailed you the details.
-
Open the handler
Open the debug handler and look at how it decides whether to answer.
Security Framework Coverage
OWASP Top 10
- A02:2025 Security Misconfiguration
- A05:2021 Security Misconfiguration
CWE
- CWE-489 Active Debug Code
- CWE-215 Insertion of Sensitive Information Into Debugging Code
CIS Controls
- CIS 16 Application Software Security
NIST CSF
- PR.AT-02 Individuals in specialized roles are provided with awareness and training so that they possess the knowledge and skills to perform relevant tasks with cybersecurity risks in mind
- PR.PS Platform Security