No console.log or console.debug in production code paths
Why it matters
Unguarded console.log calls in production code expose internal data structures — user objects, API responses, internal state — to browser consoles and server logs. CWE-532 (Insertion of Sensitive Information into Log File) applies when logged objects include user data, tokens, or application secrets. Beyond the data exposure risk, console.log in server-side code that runs on every request floods logs with noise, making real errors and security incidents harder to detect. AI-generated codebases accumulate debug logs that were never removed before shipping.
Severity rationale
Low because `console.log` in production primarily causes data leakage and log noise rather than direct security exploitation, though CWE-532 applies when logged objects contain sensitive data.
Remediation
Add an ESLint rule to flag production console calls:
"no-console": ["warn", { "allow": ["warn", "error"] }]
Replace debug logging with a structured logger that is environment-aware:
// lib/logger.ts
export const logger = {
info: (msg: string, data?: object) => {
if (process.env.NODE_ENV !== 'production') console.log(msg, data)
// In production: send to your logging service
},
error: (msg: string, error?: unknown) => console.error(msg, error)
}
Server-side route handlers should never call console.log on every request — use structured logging with sampling instead.
Detection
-
ID:
no-console-logs -
Severity:
low -
What to look for: Search source files for
console.log,console.debug,console.warn, andconsole.errorcalls in production code paths. Acceptable uses:console.errorin catch blocks for error logging (until a proper logger is set up),console.warnwithprocess.env.NODE_ENV !== 'production'guards. Not acceptable:console.logcalls left from debugging,console.login server-side code that runs on every request. -
Pass criteria: Count every
console.logandconsole.debugcall in production code paths (exclude test files and environment-guarded calls). No more than 4 unguardedconsole.logorconsole.debugcalls in production source code.console.errorin catch blocks is acceptable. Console calls guarded byprocess.env.NODE_ENV !== 'production'are acceptable. Report the count: "Found X unguarded console.log/debug calls across Y source files." -
Fail criteria: 5 or more
console.logorconsole.debugcalls found in production source code (not in test files, not environment-guarded). -
Skip (N/A) when: The project has fewer than 5 source files. Signal: fewer than 5 source files.
-
Detail on fail:
"12 console.log calls found in production code: 4 in lib/api.ts, 3 in components/DataTable.tsx, 5 in app/api/ route handlers. These log to user browser consoles and server output on every request."or"console.log statements in API route handlers expose internal data structure to server logs." -
Remediation:
console.logleft in production code leaks internal data structures to browser consoles and fills server logs with noise, making real errors harder to find.Add an ESLint rule to catch console calls:
"no-console": ["warn", { "allow": ["warn", "error"] }]For server-side logging, replace with a structured logger:
// lib/logger.ts export const logger = { info: (msg: string, data?: object) => { if (process.env.NODE_ENV !== 'production') console.log(msg, data) // In production: send to your logging service }, error: (msg: string, error?: unknown) => console.error(msg, error) }
External references
- iso-25010:2011 · maintainability.analysability — Analysability
- cwe · CWE-532 — Insertion of Sensitive Information into Log File
Taxons
History
- 2026-04-18·v1.0.0·Initial import from code-maintainability·automated