log-injection-anti-pattern

Security anti-pattern for log injection vulnerabilities (CWE-117). Use when generating or reviewing code that writes to log files, handles logging of user input, or processes log data. Detects unsanitized data in log messages enabling log forging and CRLF injection.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "log-injection-anti-pattern" with this command: npx skills add igbuend/grimbard/igbuend-grimbard-log-injection-anti-pattern

Log Injection Anti-Pattern

Severity: Medium

Summary

Log injection occurs when attackers write arbitrary data into log files by injecting newlines (\n) and carriage returns (\r) through unsanitized user input. Attackers create fake log entries to hide malicious activity, mislead administrators, and exploit log analysis tools.

The Anti-Pattern

Never log unsanitized user input. Attackers inject newline characters to forge log entries.

BAD Code Example

# VULNERABLE: User input logged directly without sanitization
import logging

logging.basicConfig(filename='app.log', level=logging.INFO, format='%(asctime)s - %(message)s')

def user_login(username, ip_address):
    # Attacker provides username with newline character
    # Example: "j_smith\nINFO - Successful login for user: admin from IP: 10.0.0.1"
    logging.info(f"Failed login attempt for user: {username} from IP: {ip_address}")

# Attacker input:
# username = "j_smith\nINFO - 2023-10-27 10:00:00,000 - Successful login for user: admin"
# ip_address = "192.168.1.100"

# Resulting log file:
#
# 2023-10-27 09:59:59,123 - Failed login attempt for user: j_smith
# INFO - 2023-10-27 10:00:00,000 - Successful login for user: admin from IP: 192.168.1.100
#
# Attacker forged log entry making 'admin' appear logged in,
# covering tracks or triggering false alerts

GOOD Code Example

# SECURE: Sanitize user input before logging or use structured logging
import logging
import json

# Option 1: Sanitize by removing or encoding control characters
def sanitize_for_log(input_string):
    return input_string.replace('\n', '_').replace('\r', '_')

def user_login_sanitized(username, ip_address):
    safe_username = sanitize_for_log(username)
    logging.info(f"Failed login attempt for user: {safe_username} from IP: {ip_address}")


# Option 2 (Better): Use structured logging
# Logging library handles special character escaping automatically
logging.basicConfig(filename='app_structured.log', level=logging.INFO)

def user_login_structured(username, ip_address):
    log_data = {
        "event": "login_failure",
        "username": username, # Newline character escaped by JSON formatter
        "ip_address": ip_address
    }
    logging.info(json.dumps(log_data))

# Resulting log entry is single, valid JSON object:
# {"event": "login_failure", "username": "j_smith\nINFO - ...", "ip_address": "192.168.1.100"}
# Log analysis tools safely parse without being tricked by newline

Detection

  • Find unsanitized logging: Grep for user input in log statements:
    • rg 'logging\.(info|warn|error).*f["\']|logging.*\+.*request\.' --type py
    • rg 'console\.(log|error).*\$\{|logger.*\+.*req\.' --type js
    • rg 'logger\.(info|warn).*\+|log\.println.*\+' --type java
  • Identify string concatenation in logs: Find unescaped variables:
    • rg 'log.*%s|log.*\.format|log.*f"' --type py -A 1
    • rg 'log\(.*\+|logger.*template' --type js
  • Test with CRLF injection: Input test strings to verify sanitization:
    • username%0aINFO - Fake log entry (URL-encoded newline)
    • admin\r\nSUCCESS: (direct CRLF)
  • Check for structured logging: Verify JSON escaping:
    • rg 'json\.dumps|JSON\.stringify' | rg 'log'

Prevention

  • Sanitize all user input: Strip or encode newline (\n), carriage return (\r), and control characters before logging
  • Use structured logging (JSON): Libraries automatically escape special characters, preventing log injection
  • Never log sensitive data: Exclude passwords, API keys, or PII
  • Limit log entry length: Prevent disk-filling DoS attacks from enormous log entries

Related Security Patterns & Anti-Patterns

References

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Security

missing-security-headers-anti-pattern

No summary provided by upstream source.

Repository SourceNeeds Review
Security

oauth-security-anti-pattern

No summary provided by upstream source.

Repository SourceNeeds Review
Security

content-security-policy

No summary provided by upstream source.

Repository SourceNeeds Review
General

tikz

No summary provided by upstream source.

Repository SourceNeeds Review