Mitigation Strategy: Structured Logging with JSON Formatter
Mitigation Strategy: Structured Logging with JSON Formatter
-
Description:
- Developer Action: In your Go code, initialize
logrus
with theJSONFormatter
. This should be done at the very beginning of your application's initialization, before any logging occurs. - Code Modification: Replace any existing
logrus.New()
calls with:log := logrus.New() log.SetFormatter(&logrus.JSONFormatter{})
- 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.
- Configuration Management: If your application uses configuration files, ensure the logging configuration specifies the JSON formatter. This prevents accidental overrides.
- Developer Action: In your Go code, initialize
-
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 thelogging
package'sinit()
function"). Provide specific file paths and function names. If partially implemented, note which parts are correct.
- Describe where in the project this is implemented (e.g., "Implemented in
-
Missing Implementation:
- Describe where this is not implemented (e.g., "Missing in the
user_authentication
module," or "Thedatabase_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.
- Describe where this is not implemented (e.g., "Missing in the
Mitigation Strategy: Contextual Logging with Fields
Mitigation Strategy: Contextual Logging with Fields
-
Description:
- Developer Action: Identify all places in your code where you log information, especially where user-supplied data is involved.
- Code Modification: Replace any instances of
log.Infof
,log.Printf
, or similar functions that directly embed user input into the log message withlog.WithFields
orlog.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")
- Incorrect (Vulnerable):
- Review: Conduct a code review to ensure all logging calls use
WithFields
appropriately and that no user input is directly concatenated into log messages. - 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 theapi
package for all request handling," or "Partially implemented; some older modules still use string formatting").
- Specify where
-
Missing Implementation:
- List specific areas where string formatting is still used with user input or where logging is done without using
WithFields
(e.g., "Thelegacy_importer
module useslog.Printf
extensively," or "Error handling in thedatabase
package needs review").
- List specific areas where string formatting is still used with user input or where logging is done without using
Mitigation Strategy: Data Masking/Redaction (Custom Hooks)
Mitigation Strategy: Data Masking/Redaction (Custom Hooks)
-
Description:
- Developer Action: Create a new Go file (e.g.,
redaction_hook.go
) to define your customlogrus
hook. - 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) }
- 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.
- 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)
- Testing: Thoroughly test the hook with various inputs to ensure it correctly redacts sensitive data and doesn't accidentally redact non-sensitive information.
- Maintainability: Store the redaction patterns in a configuration file or a dedicated module to make them easier to update and manage.
- Developer Action: Create a new Go file (e.g.,
-
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").
- Describe whether a redaction hook is implemented and how it's configured (e.g., "A redaction hook is implemented in
-
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").
- 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
Mitigation Strategy: Rate Limiting (Custom Hook) - Advanced
Mitigation Strategy: Rate Limiting (Custom Hook) - Advanced
-
Description:
- Developer Action: Create a custom
logrus
hook (similar to the redaction hook) to implement rate limiting. - Rate Limiting Algorithm: Choose a suitable rate limiting algorithm (e.g., token bucket, leaky bucket, fixed window).
- 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 }
- Configuration: Configure the rate limit (e.g., number of entries per second/minute) appropriately for your application's needs.
- Testing: Thoroughly test the hook with various log volumes to ensure it effectively limits the rate of log entries without impacting normal operation.
- 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.
- Developer Action: Create a custom
-
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:
- 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 toFatal
, but also callspanic()
.
- 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)
- Code Review: Ensure that log levels are used consistently and appropriately throughout the codebase.
- 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.
- Developer Action: Review all logging statements in your code and assign the correct log level based on the severity and purpose of the message.
-
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 ofDebug
) 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 theDebug
level").
- Describe the current log level configuration (e.g., "Log levels are set via environment variables and default to
-
Missing Implementation:
- List areas where inappropriate log levels are used (e.g., "The
database
module usesDebug
level for routine operations," or "There's no mechanism to change the log level in production").
- List areas where inappropriate log levels are used (e.g., "The