Add Secure Logging with AI Prompts

Share

TL;DR

Logs are gold for debugging but dangerous if they contain secrets. Never log passwords, tokens, full credit cards, or PII. Redact sensitive fields automatically, use structured logging, and secure log storage. These prompts help you log safely.

Logging Audit

Audit Current Logging

Audit my codebase for insecure logging practices.

Search for logging that might contain sensitive data:

  1. Request body logging: console.log(req.body) // May contain passwords logger.info({ body: req.body })
  2. User data logging: console.log(user) // May contain PII console.log('User:', JSON.stringify(user))
  3. Token/credential logging: console.log('Token:', token) console.log('Auth header:', req.headers.authorization) console.log(API Key: ${apiKey})
  4. Error logging with context: console.error('Failed:', error, requestData) // requestData may have secrets
  5. Database query logging: console.log('Query:', query) // May show credentials in connection string

Check for:

  • console.log with raw request/response objects
  • Logging entire user objects
  • Logging headers (contains auth tokens)
  • Logging form data (contains passwords)
  • Verbose debug logging in production

Sensitive Data Redaction

Implement Data Redaction

Create a utility to redact sensitive data from logs.

const sensitiveFields = 'password', 'passwd', 'secret', 'token', 'apiKey', 'api_key', 'authorization', 'auth', 'credential', 'ssn', 'creditCard', 'cardNumber', 'cvv', 'pin' ;

function redact(obj, depth = 0) { if (depth > 10) return 'MAX_DEPTH'; if (obj === null || obj === undefined) return obj; if (typeof obj !== 'object') return obj;

if (Array.isArray(obj)) { return obj.map(item => redact(item, depth + 1)); }

const redacted = {}; for (const key, value of Object.entries(obj)) { const lowerKey = key.toLowerCase();

if (sensitiveFields.some(f => lowerKey.includes(f))) {
  redacted[key] = '[REDACTED]';
} else if (typeof value === 'object') {
  redacted[key] = redact(value, depth + 1);
} else {
  redacted[key] = value;
}

} return redacted; }

// Usage logger.info('Request:', redact(req.body)); // { email: "user@example.com", password: "REDACTED" }

// Redact specific patterns function redactPatterns(str) { return str .replace(/Bearer\s+\S+/gi, 'Bearer REDACTED') .replace(/\b\d{4}-?\d{4}-?\d{4}-?\d{4}\b/g, 'CARD_REDACTED') .replace(/\bA-Za-z0-9._%+-+@A-Za-z0-9.-+.A-Z|a-z{2,}\b/g, 'EMAIL_REDACTED'); }

Logs are often less protected than databases: They get shipped to third-party services, stored in plain text, and accessed by more people. Treat logs as public and redact accordingly.

Structured Logging

Set Up Structured Logging

Set up structured logging with automatic redaction.

Using pino (fast JSON logger):

npm install pino pino-pretty

const pino = require('pino');

const logger = pino({ level: process.env.LOG_LEVEL || 'info',

// Redact sensitive paths automatically redact: { paths: 'req.headers.authorization', 'req.headers.cookie', 'req.body.password', 'req.body.token', '*.password', '*.secret', '*.apiKey' , censor: 'REDACTED' },

// Pretty print in development only transport: process.env.NODE_ENV !== 'production' ? { target: 'pino-pretty' } : undefined,

// Base fields for all logs base: { env: process.env.NODE_ENV, version: process.env.npm_package_version } });

// Usage with context logger.info({ userId: user.id, action: 'login' }, 'User logged in'); logger.error({ err, requestId }, 'Request failed');

// Request logging middleware app.use((req, res, next) => { req.log = logger.child({ requestId: crypto.randomUUID() }); req.log.info({ method: req.method, url: req.url }, 'Request received'); next(); });

Log Levels and Retention

Configure Log Levels

Set up appropriate log levels and retention.

Log levels (use appropriately):

  • fatal: System crash, immediate action needed
  • error: Operation failed, needs investigation
  • warn: Potential problem, monitoring needed
  • info: Normal operations (requests, completions)
  • debug: Detailed debugging info
  • trace: Very verbose, rarely used

Production configuration: LOG_LEVEL=info # Don't log debug/trace in production

// Never log these at any level: // - Passwords, tokens, API keys // - Full credit card numbers // - Social security numbers // - Full session tokens

// OK to log: // - User IDs (not emails in some contexts) // - Request IDs // - Timestamps // - Action types // - Sanitized error messages // - Performance metrics

Retention policies:

  • Production logs: 30-90 days
  • Security logs: 1 year (compliance)
  • Debug logs: 7 days max

Storage security:

  • Encrypt logs at rest
  • Restrict access (need-to-know)
  • Audit log access
  • Don't expose log endpoints publicly

Pro tip: Set up log alerts for security events: failed logins, permission denied errors, unusual patterns. Logs aren't just for debugging - they're your security audit trail.

Should I log user emails?

Depends on your privacy requirements. For GDPR compliance, consider logging user IDs instead of emails. If you must log emails, ensure logs are treated as PII and have appropriate retention policies.

How do I debug production issues without verbose logs?

Use request IDs to correlate logs, structured logging for searchability, and error tracking services. You can also temporarily enable debug logging for specific users or requests without enabling it globally.

Audit Your Logging

Scan your codebase for sensitive data in log statements.

Start Free Scan
AI Fix Prompts

Add Secure Logging with AI Prompts