{
    "slug": "sensitive_data_in_logs",
    "term": "Sensitive Data in Logs",
    "category": "security",
    "difficulty": "intermediate",
    "short": "Logging passwords, tokens, credit card numbers, or PII — log aggregators store data indefinitely and are often less secured than primary databases.",
    "long": "Application logs are collected by aggregators (ELK, Datadog, Splunk) where they are stored, indexed, and accessed by many more people than the primary database. Logging request parameters, exception messages containing credentials, or full user objects routinely exposes sensitive data. Structured logging makes this worse — a well-intentioned context object dumps everything. Always explicitly allowlist what gets logged rather than logging everything and filtering after.",
    "aliases": [
        "logging secrets",
        "PII in logs",
        "credential logging"
    ],
    "tags": [
        "security",
        "logging",
        "php",
        "gdpr"
    ],
    "misconception": "Logs are only seen by developers so sensitive data is acceptable — log aggregators are accessed by devops, security, support teams, and third-party SIEM tools; treat logs as semi-public.",
    "why_it_matters": "A password logged in a debug message, then shipped to an external log aggregator, means that password is now stored in plaintext in a system with weaker access controls than the auth database.",
    "common_mistakes": [
        "Logging entire request arrays: error_log(print_r($_POST, true)) — captures passwords and tokens.",
        "Logging exception messages that include SQL with bound parameters containing user data.",
        "Logging full user objects including hashed passwords and API keys.",
        "Not masking card numbers — only log last 4 digits: ****1234."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "structured_logging",
        "insufficient_logging",
        "sensitive_data_exposure",
        "grpc"
    ],
    "prerequisites": [
        "structured_logging",
        "insufficient_logging",
        "gdpr_compliance"
    ],
    "refs": [
        "https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html"
    ],
    "bad_code": "// Logs entire POST including passwords:\nerror_log('Request: ' . print_r($_POST, true));\n\n// Logs exception with credentials in message:\ntry {\n    authenticate($user, $password);\n} catch (Exception $e) {\n    $logger->error($e->getMessage()); // May contain password\n    $logger->debug('Context', ['user' => $user, 'pass' => $password]);\n}",
    "good_code": "// Explicit allowlist — only log safe fields:\n$logger->info('Login attempt', [\n    'user_id' => $user->id,\n    'ip'      => $request->ip(),\n    'success' => $authenticated,\n    // No password, no token, no PII beyond user_id\n]);\n\n// Mask sensitive values:\n$logger->debug('Payment', [\n    'card_last4' => substr($card, -4),\n    'amount'     => $amount,\n    // Never: full card number, CVV, or auth token\n]);",
    "quick_fix": "Audit your log format and scrub PII before logging — add a Monolog processor that redacts known sensitive keys (password, token, card_number, ssn) from all log context arrays",
    "severity": "critical",
    "effort": "medium",
    "created": "2026-03-16",
    "updated": "2026-04-05",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/sensitive_data_in_logs",
        "html_url": "https://codeclaritylab.com/glossary/sensitive_data_in_logs",
        "json_url": "https://codeclaritylab.com/glossary/sensitive_data_in_logs.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Sensitive Data in Logs](https://codeclaritylab.com/glossary/sensitive_data_in_logs) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/sensitive_data_in_logs"
            }
        }
    }
}