Secure Error Handling and Logging

Secure Error Handling and Logging

Proper error handling and logging are essential for both security and debugging. However, error messages must not reveal sensitive information that could help attackers. Implement comprehensive logging while ensuring that sensitive data is never logged.

import logging
import traceback
from functools import wraps
import re
from typing import Any, Dict

class SecureLogger:
    def __init__(self, name: str):
        self.logger = logging.getLogger(name)
        self.sensitive_patterns = [
            (r'\b\d{16}\b', '[CREDIT_CARD]'),  # Credit card numbers
            (r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', '[EMAIL]'),
            (r'password["\']?\s*[:=]\s*["\']?([^"\']+)["\']?', 'password: [REDACTED]'),
            (r'api[_-]?key["\']?\s*[:=]\s*["\']?([^"\']+)["\']?', 'api_key: [REDACTED]'),
        ]
    
    def sanitize_message(self, message: str) -> str:
        """Remove sensitive information from log messages"""
        sanitized = str(message)
        
        for pattern, replacement in self.sensitive_patterns:
            sanitized = re.sub(pattern, replacement, sanitized, flags=re.IGNORECASE)
        
        return sanitized
    
    def log_info(self, message: str, extra: Dict[str, Any] = None):
        """Log info level message with sanitization"""
        safe_message = self.sanitize_message(message)
        self.logger.info(safe_message, extra=extra or {})
    
    def log_error(self, message: str, exception: Exception = None, extra: Dict[str, Any] = None):
        """Log error with sanitized exception details"""
        safe_message = self.sanitize_message(message)
        
        if exception:
            # Sanitize exception message and traceback
            safe_exception = self.sanitize_message(str(exception))
            safe_traceback = self.sanitize_message(traceback.format_exc())
            
            self.logger.error(
                f"{safe_message}. Exception: {safe_exception}",
                extra={
                    **(extra or {}),
                    'traceback': safe_traceback
                }
            )
        else:
            self.logger.error(safe_message, extra=extra or {})
    
    def log_security_event(self, event_type: str, details: Dict[str, Any]):
        """Log security-related events"""
        # Sanitize details
        safe_details = {}
        for key, value in details.items():
            if key in ['password', 'token', 'api_key', 'secret']:
                safe_details[key] = '[REDACTED]'
            else:
                safe_details[key] = self.sanitize_message(str(value))
        
        self.logger.warning(
            f"SECURITY_EVENT: {event_type}",
            extra={'security_details': safe_details}
        )

def handle_errors(logger: SecureLogger):
    """Decorator for secure error handling"""
    def decorator(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            try:
                return f(*args, **kwargs)
            except ValidationError as e:
                # Known validation errors - safe to log details
                logger.log_info(f"Validation error in {f.__name__}: {str(e)}")
                return {"error": "Invalid input provided"}, 400
            except DatabaseError as e:
                # Database errors might contain sensitive schema info
                logger.log_error(f"Database error in {f.__name__}", exception=e)
                return {"error": "A database error occurred"}, 500
            except Exception as e:
                # Unknown errors - log full details but return generic message
                logger.log_error(f"Unexpected error in {f.__name__}", exception=e)
                return {"error": "An unexpected error occurred"}, 500
        
        return wrapper
    return decorator

# Usage example
logger = SecureLogger(__name__)

@handle_errors(logger)
def process_payment(user_id: int, card_number: str, amount: float):
    """Example function with secure error handling"""
    # This will be logged as: "Processing payment for user 123 with card [CREDIT_CARD]"
    logger.log_info(f"Processing payment for user {user_id} with card {card_number}")
    
    # Process payment...
    
    return {"status": "success"}

This comprehensive approach to Python security best practices provides a solid foundation for building secure applications. The key principles include never trusting user input, using parameterized queries, implementing proper authentication, and maintaining secure logging practices. Regular security audits and staying updated with the latest security advisories for Python packages ensure ongoing protection against emerging threats.## JavaScript Security Vulnerabilities

JavaScript's ubiquitous presence in modern web development makes it a critical area for security focus. Running in browsers, servers (Node.js), and even IoT devices, JavaScript code faces unique security challenges across different environments. This chapter examines the most common JavaScript security vulnerabilities, their exploitation methods, and the impact they can have on applications. Understanding these vulnerabilities is essential for developers to write secure JavaScript code and protect their applications from attacks.