Debug console.log statements left in production code expose internal data structures, user data, and system internals in the browser console and server logs — visible to anyone who opens DevTools or has log access. ISO 25010:2011 §6.5.2 classifies this as a maintainability defect. Beyond the information exposure risk, uncontrolled log output fills log aggregators with noise, makes filtering for real errors harder, and signals to engineers that the codebase lacks basic hygiene standards.
Low because console.log leakage is primarily a hygiene and information-exposure issue rather than an immediate exploitable vulnerability, but it degrades log quality and can expose sensitive internal state.
Remove debug console.log statements from production source files. For intentional production logging, use a level-aware logger so output can be controlled by environment:
// src/lib/logger.ts
const isDev = process.env.NODE_ENV === 'development'
export const logger = {
info: (msg: string, data?: unknown) => {
if (isDev) console.info('[info]', msg, data)
},
error: (msg: string, error?: unknown) => {
console.error('[error]', msg, error) // always log errors
},
}
Enforce via ESLint so it is caught in CI:
{ "rules": { "no-console": ["error", { "allow": ["error", "warn"] }] } }
ID: code-quality-essentials.testing.no-console-log
Severity: low
What to look for: Search all files in src/, app/, lib/, and pages/ directories for console.log( — excluding test files (*.test.*, *.spec.*, __tests__/) and development-only files. Each console.log found in production code is a debugging artifact that was left in accidentally. Production applications should use a structured logger (e.g., pino, winston, consola, or a custom logger utility) so output can be controlled by log level and configured per environment. Also check for console.error and console.warn — these are acceptable for logging actual errors in production, but raw console.log with debugging strings is not. Check the ESLint config for no-console rule presence.
Pass criteria: Count all console.log occurrences in production source files. No console.log calls in production source files, OR ESLint is configured with no-console: error to prevent this automatically with at least 1 verified location.
Fail criteria: console.log calls present in production source files outside of test utilities.
Skip (N/A) when: Never — this applies to all projects with a build step.
Detail on fail: "Found N instances of console.log in production code (e.g., src/components/Header.tsx, src/lib/api.ts)" (substitute actual locations)
Remediation: Remove debugging console.log statements. For logging that should remain in production, use a level-aware logger:
// src/lib/logger.ts
const isDev = process.env.NODE_ENV === 'development'
export const logger = {
info: (msg: string, data?: unknown) => {
if (isDev) console.info('[info]', msg, data)
},
error: (msg: string, error?: unknown) => {
console.error('[error]', msg, error) // always log errors
},
}
To catch this in CI, add the ESLint rule:
{ "rules": { "no-console": ["error", { "allow": ["error", "warn"] }] } }