Weakness reference
CWE-215

Insertion of Sensitive Information Into Debugging Code

This weakness occurs when developers include sensitive data—such as passwords, API keys, database credentials, or personal information—directly in debugging…

01Summary

This weakness occurs when developers include sensitive data—such as passwords, API keys, database credentials, or personal information—directly in debugging statements, log output, or error messages. If debugging code is left active in production, that sensitive information becomes exposed to anyone who can access logs, error pages, or memory dumps.

02How It Happens

Developers often add debug output during development to troubleshoot issues: printing variables, logging function parameters, or dumping object state. When sensitive data flows through these debug statements—a user's password during login, an API key during authentication, a database connection string during initialization—it gets written to logs or displayed on screen. The problem compounds when:

- Debug mode remains enabled in production configuration. - Logging levels are set too verbose and capture full request/response bodies. - Error pages display stack traces or variable dumps to end users. - Log files are stored in web-accessible directories or backed up without encryption. - Developers assume "debug code will be removed before release" but it isn't.

03Real-World Impact

Exposed credentials in logs can lead to direct account compromise, unauthorized database access, or API abuse. An attacker who gains read access to log files—through a separate vulnerability, misconfigured permissions, or a backup leak—can extract credentials and pivot to other systems. Even internal exposure is risky: a disgruntled employee, contractor, or compromised internal account can harvest credentials from debug output. In regulated environments (healthcare, finance, PCI-DSS), this exposure may trigger compliance violations and mandatory breach notifications.

04Vulnerable & Fixed Patterns

Vulnerable pattern
import logging

def authenticate_user(username, password):
    logging.debug(f"Attempting login for user: {username}, password: {password}")
    
    if check_credentials(username, password):
        api_key = generate_api_key(username)
        logging.debug(f"Generated API key: {api_key}")
        return api_key
    return None

Why it's vulnerable:
The password and generated API key are written directly to debug logs. If debug logging is enabled in production, these credentials are exposed in log files.

Fixed pattern
import logging

def authenticate_user(username, password):
    logging.debug(f"Attempting login for user: {username}")
    
    if check_credentials(username, password):
        api_key = generate_api_key(username)
        logging.info(f"Login successful for user: {username}")
        return api_key
    return None
Vulnerable pattern
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

function connect_database($db_host, $db_user, $db_pass) {
    error_log("Connecting to database: host=$db_host, user=$db_user, pass=$db_pass");
    
    $conn = mysqli_connect($db_host, $db_user, $db_pass);
    if (!$conn) {
        echo "Connection failed: " . mysqli_connect_error();
    }
    return $conn;
}
?>

Why it's vulnerable:
Database credentials are logged in plain text and error messages are displayed to users. Both expose sensitive connection details.

Fixed pattern
<?php
if (defined('WP_DEBUG') && WP_DEBUG) {
    error_reporting(E_ALL);
    ini_set('display_errors', 0);
    ini_set('log_errors', 1);
}

function connect_database($db_host, $db_user, $db_pass) {
    error_log("Attempting database connection");
    
    $conn = mysqli_connect($db_host, $db_user, $db_pass);
    if (!$conn) {
        error_log("Database connection failed");
        return false;
    }
    return $conn;
}
?>

05Prevention Checklist

Never log passwords, API keys, tokens, or connection strings.
If you must log authentication events, log only the username or user ID, not credentials.
Disable debug output in production.
Use environment-based configuration (DEBUG=False in production, DEBUG=True only locally) and never commit debug-enabled settings to version control.
Sanitize error messages shown to users.
Display generic errors ("Login failed") to end users; log detailed errors only to server-side logs with restricted access.
Rotate and audit logs regularly.
Ensure log files are stored outside the web root, encrypted at rest, and accessible only to authorized personnel.
Use a secrets management system.
Store credentials in environment variables, vaults (e.g., HashiCorp Vault), or managed services—never hardcoded or in debug output.
Review code for debug statements before deployment.
Use pre-commit hooks or code review checklists to catch console.log(), print(), var_dump(), and error_log() calls that reference sensitive data.

06Signs You May Already Be Affected

Check your application logs and error pages for exposed credentials, API keys, or database connection strings. If your error pages display stack traces or variable dumps to visitors, or if your log files contain plaintext passwords or tokens, you are at risk. Review recent log files for any entries that include authentication data, and check whether debug mode is enabled in your production configuration files.

07Related Recent Vulnerabilities