Skip to content

Latest commit

 

History

History
226 lines (181 loc) · 13.5 KB

File metadata and controls

226 lines (181 loc) · 13.5 KB

Mitigation Strategies Analysis for sirupsen/logrus

Mitigation Strategy: Structured Logging with JSON Formatter

  • Description:

    1. Developer Action: In your Go code, initialize logrus with the JSONFormatter. This should be done at the very beginning of your application's initialization, before any logging occurs.
    2. Code Modification: Replace any existing logrus.New() calls with:
      log := logrus.New()
      log.SetFormatter(&logrus.JSONFormatter{})
    3. Verification: Run your application and examine the log output. It should be valid JSON, with each log entry represented as a JSON object. Ensure no plain text log entries are present.
    4. Configuration Management: If your application uses configuration files, ensure the logging configuration specifies the JSON formatter. This prevents accidental overrides.
  • Threats Mitigated:

    • Log Injection/Forging (High Severity): Prevents attackers from injecting newline characters or other control characters to create fake log entries or manipulate the log's structure. JSON escaping neutralizes these attempts.
    • Log Parsing Issues (Medium Severity): Makes log parsing by log analysis tools (e.g., SIEM systems) more reliable and less prone to errors caused by unexpected characters in log messages.
  • Impact:

    • Log Injection/Forging: Risk reduced from High to Low. JSON formatting is a fundamental defense against log injection.
    • Log Parsing Issues: Risk reduced from Medium to Low. Consistent JSON structure simplifies parsing.
  • Currently Implemented:

    • Describe where in the project this is implemented (e.g., "Implemented in main.go during application initialization," or "Implemented in the logging package's init() function"). Provide specific file paths and function names. If partially implemented, note which parts are correct.
  • Missing Implementation:

    • Describe where this is not implemented (e.g., "Missing in the user_authentication module," or "The database_connector package still uses the default text formatter"). Be specific about file paths and function names. List all instances where the text formatter is still used or where logging is done without setting a formatter.

Mitigation Strategy: Contextual Logging with Fields

Mitigation Strategy: Contextual Logging with Fields

  • Description:

    1. Developer Action: Identify all places in your code where you log information, especially where user-supplied data is involved.
    2. Code Modification: Replace any instances of log.Infof, log.Printf, or similar functions that directly embed user input into the log message with log.WithFields or log.WithField.
      • Incorrect (Vulnerable):
        log.Infof("User %s logged in", username) // Vulnerable to injection
      • Correct (Secure):
        log.WithFields(logrus.Fields{
            "user": username,
            "event": "login",
        }).Info("User logged in")
    3. Review: Conduct a code review to ensure all logging calls use WithFields appropriately and that no user input is directly concatenated into log messages.
    4. Consistency: Establish a coding standard that mandates the use of WithFields for all logging.
  • Threats Mitigated:

    • Log Injection/Forging (Medium Severity): Reduces the attack surface for log injection by separating potentially malicious input from the main log message. Even if input contains malicious characters, it's treated as data within a field, not as part of the log message's structure.
    • Data Exposure (Medium Severity): By encouraging structured logging, it implicitly promotes thinking about what data is being logged, reducing the chance of accidentally logging entire objects or sensitive fields.
  • Impact:

    • Log Injection/Forging: Risk reduced from Medium to Low (when combined with JSON formatting).
    • Data Exposure: Risk reduced from Medium to Low/Medium (depending on the thoroughness of data selection).
  • Currently Implemented:

    • Specify where WithFields is consistently used (e.g., "Used consistently in the api package for all request handling," or "Partially implemented; some older modules still use string formatting").
  • Missing Implementation:

    • List specific areas where string formatting is still used with user input or where logging is done without using WithFields (e.g., "The legacy_importer module uses log.Printf extensively," or "Error handling in the database package needs review").

Mitigation Strategy: Data Masking/Redaction (Custom Hooks)

  • Description:

    1. Developer Action: Create a new Go file (e.g., redaction_hook.go) to define your custom logrus hook.
    2. Hook Implementation: Implement the logrus.Hook interface:
      package logging // Or your appropriate package
      
      import (
          "regexp"
          "github.com/sirupsen/logrus"
      )
      
      type RedactionHook struct {
          Patterns []*regexp.Regexp
      }
      
      func (hook *RedactionHook) Levels() []logrus.Level {
          return logrus.AllLevels
      }
      
      func (hook *RedactionHook) Fire(entry *logrus.Entry) error {
          for _, pattern := range hook.Patterns {
              //Redact Message
              entry.Message = pattern.ReplaceAllString(entry.Message, "[REDACTED]")
              //Redact fields
              for key, value := range entry.Data {
                  if strVal, ok := value.(string); ok {
                      entry.Data[key] = pattern.ReplaceAllString(strVal, "[REDACTED]")
                  }
              }
          }
          return nil
      }
      
       // Function to create and add the hook
      func AddRedactionHook(log *logrus.Logger, patterns []string) {
          hook := &RedactionHook{}
          for _, p := range patterns{
              hook.Patterns = append(hook.Patterns, regexp.MustCompile(p))
          }
          log.AddHook(hook)
      }
    3. Regular Expressions: Define regular expressions to match sensitive data patterns (e.g., credit card numbers, Social Security numbers, API keys). Be very careful with these regular expressions to avoid false positives. Test them thoroughly.
    4. Hook Registration: In your application's initialization, add the hook to your logrus instance:
      //In main.go or similar place
      import "your_project/logging"
      //...
      
      log := logrus.New()
      log.SetFormatter(&logrus.JSONFormatter{}) // Use JSON formatter!
      
      patterns := []string{
          `\b(?:\d[ -]*?){13,16}\b`, // Example: Credit card numbers
          `\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b`,  //Example: Email
          // Add more patterns as needed
      }
      logging.AddRedactionHook(log, patterns)
    5. Testing: Thoroughly test the hook with various inputs to ensure it correctly redacts sensitive data and doesn't accidentally redact non-sensitive information.
    6. Maintainability: Store the redaction patterns in a configuration file or a dedicated module to make them easier to update and manage.
  • Threats Mitigated:

    • Sensitive Data Exposure (High Severity): Prevents sensitive data from being written to the logs, even if it's accidentally included in log messages or fields.
  • Impact:

    • Sensitive Data Exposure: Risk reduced from High to Very Low (if implemented correctly and comprehensively).
  • Currently Implemented:

    • Describe whether a redaction hook is implemented and how it's configured (e.g., "A redaction hook is implemented in logging/redaction_hook.go and redacts credit card numbers and email addresses," or "No redaction hook is currently implemented").
  • Missing Implementation:

    • If no hook is implemented, state this clearly. If a hook is partially implemented, list the missing patterns or areas where it's not applied (e.g., "The redaction hook doesn't cover Social Security numbers," or "The hook is not applied to logs from the billing module").

Mitigation Strategy: Rate Limiting (Custom Hook) - Advanced

  • Description:

    1. Developer Action: Create a custom logrus hook (similar to the redaction hook) to implement rate limiting.
    2. Rate Limiting Algorithm: Choose a suitable rate limiting algorithm (e.g., token bucket, leaky bucket, fixed window).
    3. Hook Implementation: Implement the logrus.Hook interface and the chosen algorithm. The hook should track the number of log entries within a specific time window and either discard or delay entries that exceed the limit.
      // (Conceptual Example - Token Bucket)
      type RateLimitHook struct {
          // ... (Implementation details for token bucket) ...
      }
      
      func (hook *RateLimitHook) Levels() []logrus.Level {
          return logrus.AllLevels
      }
      
      func (hook *RateLimitHook) Fire(entry *logrus.Entry) error {
          if hook.Allow() { // Check if rate limit allows the entry
              return nil // Allow the entry
          }
          return errors.New("log rate limit exceeded") // Discard the entry
      }
    4. Configuration: Configure the rate limit (e.g., number of entries per second/minute) appropriately for your application's needs.
    5. Testing: Thoroughly test the hook with various log volumes to ensure it effectively limits the rate of log entries without impacting normal operation.
    6. Error Handling: Decide how to handle rate-limited log entries. You might discard them, delay them, or log them to a separate, lower-priority log file.
  • Threats Mitigated:

    • Denial of Service (DoS) (Medium Severity): Helps prevent attackers from flooding your logs with a large number of entries.
  • Impact:

    • DoS: Risk reduced from Medium to Low/Medium (depending on the effectiveness of the rate limiting algorithm and configuration).
  • Currently Implemented:

    • Describe whether a rate limiting hook is implemented and how it's configured (e.g., "A rate limiting hook is implemented using a token bucket algorithm and limits logs to 100 entries per second," or "No rate limiting hook is currently implemented").
  • Missing Implementation:

    • If no hook is implemented, state this. If partially implemented, describe the missing aspects or areas where it's not applied.

Mitigation Strategy: Appropriate Log Levels

Mitigation Strategy: Appropriate Log Levels

  • Description:

    1. Developer Action: Review all logging statements in your code and assign the correct log level based on the severity and purpose of the message.
      • Debug: Detailed information for debugging.
      • Info: General information about application operation.
      • Warn: Potentially harmful situations.
      • Error: Errors that prevent normal operation.
      • Fatal: Critical errors that cause the application to terminate.
      • Panic: Similar to Fatal, but also calls panic().
    2. Configuration: Configure your application to use different log levels in different environments (e.g., Debug in development, Info in production). This can be done through environment variables or configuration files.
      // Example using environment variable
      logLevel := os.Getenv("LOG_LEVEL")
      if logLevel == "" {
          logLevel = "info" // Default to Info
      }
      level, err := logrus.ParseLevel(logLevel)
      if err != nil {
          log.WithError(err).Fatal("Invalid log level")
      }
      log.SetLevel(level)
    3. Code Review: Ensure that log levels are used consistently and appropriately throughout the codebase.
    4. Dynamic Level Change: Consider implementing a mechanism to dynamically change the log level at runtime (e.g., through an API endpoint or a configuration file change) for troubleshooting purposes.
  • Threats Mitigated:

    • Denial of Service (DoS) (Low Severity): Reduces the volume of log data generated, especially in production environments.
    • Sensitive Data Exposure (Low Severity): Using higher log levels (e.g., Info instead of Debug) in production reduces the chance of accidentally logging sensitive debugging information.
  • Impact:

    • DoS: Risk reduced from Low to Very Low.
    • Sensitive Data Exposure: Risk reduced from Low to Very Low.
  • Currently Implemented:

    • Describe the current log level configuration (e.g., "Log levels are set via environment variables and default to Info in production," or "All logging is currently at the Debug level").
  • Missing Implementation:

    • List areas where inappropriate log levels are used (e.g., "The database module uses Debug level for routine operations," or "There's no mechanism to change the log level in production").