Skip to content

🔴 CRITICAL: Information Disclosure - Full Error Objects Logged to Console/Files #277

@PunGrumpy

Description

@PunGrumpy

🔴 CRITICAL: Information Disclosure - Full Error Objects Logged to Console/Files

Security Vulnerability Report

Issue #277 | Severity: 🔴 CRITICAL | Type: Information Disclosure (CWE-532, CWE-215)


Executive Summary

Logixlysia exposes full error objects to console and log files without sanitization, creating a critical information disclosure vulnerability. Error objects can contain sensitive data including API keys, database credentials, authentication tokens, PII, and other confidential information that should never be logged.

Affected: All versions of Logixlysia
Current Version: 6.3.1 (Vulnerable)
Status: ⚠️ Needs Immediate Fix


Vulnerability Details

Problem

The logger passes entire error objects directly to logging transports without sanitizing or filtering sensitive fields. This means any sensitive data attached to an error object will be permanently written to:

  • Console output
  • Log files
  • External logging services (datadog, sentry, etc.)

Root Cause

Two main code paths expose error objects unsanitized:

1. Handle HTTP Error Handler (packages/logixlysia/src/logger/handle-http-error.ts:44)

const data: Record<string, unknown> = { status, message, error }  // ← CRITICAL: Entire error object included

logToTransports({ level, request, data, store, options })

const { main, contextLines } = formatLogOutput({
  level,
  request,
  data,  // ← Error object is passed through unfiltered
  store,
  options
})

2. Context Tree Builder (packages/logixlysia/src/logger/create-logger.ts:311)

export const buildContextTreeLines = (
  level: LogLevel,
  data: Record<string, unknown>,
  options: Options
): string[] => {
  // ...
  if (level === 'ERROR' && 'error' in data && data.error !== undefined) {
    const msg = parseError(data.error)
    if (msg) {
      entries.push(['error', msg])  // ← Error included in context tree
    }
  }
}

Impact Assessment

Sensitive Data Exposure Risk

Error objects commonly contain:

  • 🔑 API keys and authentication tokens (apiKey, token, Authorization)
  • 🔐 Database credentials and connection strings (password, db_password)
  • 📍 Internal system paths and configuration details
  • 📊 Stack traces revealing internal architecture
  • 👤 Personal information (names, emails, phone numbers)
  • 💳 Financial data (credit card numbers, payment tokens)
  • 🔒 OAuth tokens and session identifiers

Real-World Attack Scenarios

Scenario 1: Accidental Credential Exposure

// Developer accidentally includes credentials in error
const error = new Error('Database connection failed');
error.password = 'super-secret-password-123';
error.apiKey = 'sk_live_51234567890abcdef';
throw error;

// Logixlysia logs the entire error object including sensitive fields
// Output written to console, files, and external services

Scenario 2: Log File Access Attack

📋 Log File (world-readable on misconfigured server):
🟣 ERROR [2026-04-12 20:30:34] Database Error
  ├─ error: Connection failed
  ├─ error.password: [EXPOSED]
  ├─ error.apiKey: [EXPOSED]
  └─ error.connectionString: [EXPOSED]
  
→ Attacker gains database access via exposed credentials

Compliance Impact

  • GDPR violations (unauthorized PII processing)
  • CCPA violations (personal information disclosure)
  • PCI-DSS violations (payment card data exposure)
  • HIPAA violations (health information exposure)
  • SOC 2 audit failures

Business Impact

  • 🚨 Unauthorized access to APIs and databases via leaked credentials
  • 📉 Customer trust loss and brand damage
  • 💰 Financial harm from account takeovers
  • ⚖️ Legal liability and compliance penalties
  • 🔍 Regulatory investigation triggers

Proof of Concept

// User code throwing error with sensitive data
try {
  // Some operation
} catch (err) {
  // Error might contain sensitive properties
  const error = new Error('Operation failed');
  error.apiKey = process.env.STRIPE_API_KEY;
  error.dbPassword = process.env.DB_PASSWORD;
  
  throw error;  // Passed to Logixlysia
}

// Logixlysia logs: Full error object with all properties
// 🟣 ERROR [2026-04-12 20:31:45] Operation failed
//    error.apiKey: sk_live_3a6b8c9d0e1f2g3h4i5j6k7l
//    error.dbPassword: postgres_password_123

Recommended Solutions

Option 1: Sanitize Error Objects (⭐ Recommended)

Approach: Only log error name and message, never the full object.

const sanitizeError = (error: unknown): string => {
  if (!(error instanceof Error)) {
    return String(error);
  }
  
  // Only log message and name, not the entire object or stack
  return `${error.name}: ${error.message}`;
};

// In handle-http-error.ts
const data: Record<string, unknown> = { 
  status, 
  message,
  error: sanitizeError(error)  // ← Sanitized, not full object
};

Pros:

  • ✅ Simple and effective
  • ✅ No sensitive data leakage
  • ✅ Maintains useful error context

Cons:

  • ⚠️ Loses custom error properties

Option 2: Redact Sensitive Fields

Approach: Filter known sensitive field names and replace with [REDACTED].

const SENSITIVE_KEYS = [
  'password',
  'token',
  'apiKey',
  'api_key',
  'secret',
  'authorization',
  'auth',
  'creditCard',
  'ssn',
  'privateKey',
  'connectionString',
  'password_hash'
];

const redactError = (error: unknown): Record<string, unknown> => {
  if (!(error instanceof Error)) {
    return { message: String(error) };
  }
  
  const redacted: Record<string, unknown> = {};
  for (const [key, value] of Object.entries(error)) {
    if (SENSITIVE_KEYS.some(k => key.toLowerCase().includes(k))) {
      redacted[key] = '[REDACTED]';
    } else {
      redacted[key] = value;
    }
  }
  return redacted;
};

Pros:

  • ✅ Preserves custom error properties
  • ✅ Works with existing code

Cons:

  • ⚠️ Redaction list must be maintained
  • ⚠️ New sensitive field names might be missed

Option 3: Configurable Error Logging (⭐ Best for Users)

Approach: Add security configuration options.

export interface Options {
  config?: {
    // ... existing config
    
    // Security options
    sanitizeErrors?: boolean;           // Default: true
    redactSensitiveFields?: boolean;    // Default: true
    allowedErrorFields?: string[];      // Whitelist approach
    errorMaxLength?: number;            // Truncate long values
  }
}

Pros:

  • ✅ Flexible for different use cases
  • ✅ Users can choose security level
  • ✅ Backward compatible with flag

Cons:

  • ⚠️ More code to maintain

Files Requiring Changes

  1. packages/logixlysia/src/logger/handle-http-error.ts - Remove full error object
  2. packages/logixlysia/src/logger/create-logger.ts - Sanitize error in buildContextTreeLines
  3. packages/logixlysia/src/interfaces.ts - Add security config options
  4. packages/logixlysia/src/utils/error.ts - Implement error parsing/sanitization

Release Plan

Immediate (This Week)

  • Implement error sanitization
  • Add security configuration options
  • Write comprehensive tests
  • Update documentation

Release (Next Version)

  • Release as patch version with security fix (6.3.2)
  • Create SECURITY.md with advisory
  • Notify users of vulnerability and fix

Post-Release

  • Monitor for adoption
  • Support user migration

References

  • CWE-532: Insertion of Sensitive Information into Log File
  • CWE-215: Information Exposure Through Debug Information
  • OWASP A09:2021: Security Logging and Monitoring Failures
  • OWASP: Error Handling Best Practices

Timeline

  • Discovery: April 12, 2026
  • Report Date: April 12, 2026
  • Status: 🔴 Open - Needs Immediate Fix
  • Priority: URGENT - Critical Security Vulnerability

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions