Mitigation Strategy: Never Log Sensitive Data Directly (Serilog Configuration & Usage)
-
Description:
- Identify Sensitive Data: (Same as before - this is a prerequisite, even if not Serilog-specific).
- Refactor Logging Statements (Serilog Usage): Modify Serilog logging calls to exclude sensitive fields. This is the core Serilog-specific action.
- Example (C#):
// BAD: Logging the entire user object Log.Information("User logged in: {@User}", user); // GOOD: Logging only non-sensitive properties Log.Information("User logged in: {Username}", user.Username);
- Example (C#):
- Implement Custom Formatters/Enrichers (Serilog Configuration): Create custom Serilog
ITextFormatter
orILogEventEnricher
implementations to automatically redact or mask sensitive data before it reaches the console sink. This is a key Serilog-specific configuration step.- Example (Custom Formatter - Simplified):
public class SafeUserFormatter : ITextFormatter { public void Format(LogEvent logEvent, TextWriter output) { // ... (Logic to redact sensitive data from logEvent.Properties) ... } } // Configure Serilog to use the custom formatter: Log.Logger = new LoggerConfiguration() .WriteTo.Console(formatter: new SafeUserFormatter()) .CreateLogger();
- Example (Custom Enricher - Simplified):
public class SensitiveDataEnricher : ILogEventEnricher { public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) { // ... (Logic to remove or redact sensitive properties) ... } } // Configure Serilog to use the custom enricher: Log.Logger = new LoggerConfiguration() .Enrich.With(new SensitiveDataEnricher()) .WriteTo.Console() .CreateLogger();
- Example (Custom Formatter - Simplified):
- Use Serilog's Destructuring: Control how Serilog destructures objects for logging. Use
@
(destructure-by-value) or$
(destructure-by-string) appropriately to avoid accidentally exposing sensitive data within complex objects. This is a Serilog usage detail. - Regular Audits of Serilog Configuration: Ensure the configuration doesn't accidentally expose sensitive data through formatters or enrichers.
-
Threats Mitigated:
- Information Disclosure (High Severity): Prevents sensitive data from being written to the console.
- Compliance Violations (High Severity): Helps meet regulatory requirements.
- Reputational Damage (High Severity): Reduces the risk of data breaches.
- Credential Theft (High Severity): Prevents credential exposure.
-
Impact:
- Information Disclosure: Risk significantly reduced (near elimination with correct implementation).
- Compliance Violations: Risk significantly reduced.
- Reputational Damage: Risk significantly reduced.
- Credential Theft: Risk significantly reduced.
-
Currently Implemented:
- Example: Partially. Basic exclusion of passwords in
AuthenticationService.cs
. Key Vault integration for API keys inApiService.cs
.
- Example: Partially. Basic exclusion of passwords in
-
Missing Implementation:
- Example: Need a comprehensive custom formatter or enricher for consistent handling of all sensitive data types across the application. Need a code-wide audit focused on Serilog usage.
Mitigation Strategy: Control Log Verbosity (Serilog Configuration)
-
Description:
- Set
MinimumLevel
(Serilog Configuration): Configure Serilog'sMinimumLevel
setting specifically for the console sink.- Example (C#):
Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() // Global minimum .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning) // Console-specific minimum .CreateLogger();
- Use
restrictedToMinimumLevel
parameter inWriteTo.Console()
to set a console-specific minimum level, overriding the global minimum if needed.
- Example (C#):
- Use Filtering (Serilog Configuration): Use Serilog's filtering capabilities to selectively log messages to the console based on source, context, or other properties.
- Example (C#):
Log.Logger = new LoggerConfiguration() .WriteTo.Console() .Filter.ByExcluding(Matching.FromSource("MyApplication.NoisyModule")) // Exclude from console .CreateLogger();
- Example (C#):
- Dynamic Log Level Adjustment (Serilog Usage -
LoggingLevelSwitch
): Use Serilog'sLoggingLevelSwitch
to dynamically control the console sink's log level at runtime.- Example (C#):
var levelSwitch = new LoggingLevelSwitch(LogEventLevel.Warning); // Initial level Log.Logger = new LoggerConfiguration() .MinimumLevel.ControlledBy(levelSwitch) // Controlled by the switch .WriteTo.Console() .CreateLogger(); // Later, to change the level: levelSwitch.MinimumLevel = LogEventLevel.Debug;
- Example (C#):
- Set
-
Threats Mitigated:
- Denial of Service (DoS) (Medium Severity): Reduces console output volume.
- Performance Degradation (Low Severity): Less logging improves performance.
- Information Overload (Low Severity): Improves log readability.
-
Impact:
- Denial of Service (DoS): Risk significantly reduced.
- Performance Degradation: Risk moderately reduced.
- Information Overload: Risk significantly reduced.
-
Currently Implemented:
- Example:
MinimumLevel
set toInformation
globally. Filtering used to exclude some noisy modules.
- Example:
-
Missing Implementation:
- Example: Need to implement
LoggingLevelSwitch
for dynamic control, especially for the console sink.
- Example: Need to implement
Mitigation Strategy: Structured Logging (Serilog Usage)
-
Description:
- Always Use Structured Logging API (Serilog Usage): Use Serilog's structured logging API exclusively. This is the core Serilog-specific action.
- Example (C#):
// BAD: String concatenation Log.Information("User " + username + " logged in."); // GOOD: Structured logging Log.Information("User {Username} logged in.", username);
- Example (C#):
- Consistent Property Names (Serilog Usage Best Practice): Use consistent property names for easier querying.
- Review Existing Code for Serilog Usage: Ensure all Serilog calls use the structured logging API.
- Always Use Structured Logging API (Serilog Usage): Use Serilog's structured logging API exclusively. This is the core Serilog-specific action.
-
Threats Mitigated:
- Log Injection (Medium Severity): Prevents injection of malicious characters.
- Data Parsing Errors (Low Severity): Improves log parsing.
-
Impact:
- Log Injection: Risk significantly reduced.
- Data Parsing Errors: Risk significantly reduced.
-
Currently Implemented:
- Example: Mostly implemented; general guideline to use structured logging.
-
Missing Implementation:
- Example: Code review needed to find and fix any remaining string concatenation in Serilog calls, especially in older code.
Mitigation Strategy: Avoid Logging Untrusted Input Directly (Serilog Usage)
-
Description:
- Identify Untrusted Input: (Same as before - prerequisite).
- Sanitize Input Before Serilog Call (Serilog Usage Context): Crucially, sanitization must happen before the data is passed to Serilog.
- Example (C#):
string userInput = GetUserInput(); string sanitizedInput = SanitizeInput(userInput); // Sanitize *before* logging Log.Information("User input: {SanitizedInput}", sanitizedInput); // Log the sanitized value
- Example (C#):
- Consider Alternatives to Logging Raw Input (Serilog Usage Decision): Instead of logging the (sanitized) input directly, consider logging a hash, a truncated version, or a reference ID. This is a decision made when using Serilog.
-
Threats Mitigated:
- Log Injection (Medium Severity): Prevents injection via untrusted input.
- Cross-Site Scripting (XSS) (Medium Severity): If log data is displayed in a web UI (though this is less relevant to the console sink itself).
- Data Corruption (Low Severity): Prevents malformed input from corrupting logs.
-
Impact:
- Log Injection: Risk significantly reduced.
- Cross-Site Scripting (XSS): Risk reduced (if applicable).
- Data Corruption: Risk reduced.
-
Currently Implemented:
- Example: Partially. Input sanitization in web app, but not consistently before all Serilog calls.
-
Missing Implementation:
- Example: Need explicit sanitization steps before logging any untrusted data, especially in
ApiInputHandler.cs
.
- Example: Need explicit sanitization steps before logging any untrusted data, especially in
Mitigation Strategy: Output Encoding (Serilog and Console Configuration)
-
Description:
- Identify the Encoding: Determine the character encoding used by your console and your application. UTF-8 is generally recommended.
- Configure the Console: Ensure that the console is configured to use the correct encoding. This is usually done at the operating system or terminal level.
- Windows: Use the
chcp
command (e.g.,chcp 65001
for UTF-8). - Linux/macOS: Typically uses UTF-8 by default.
- Windows: Use the
- Configure Serilog (if necessary): While Serilog itself doesn't directly control the console's output encoding, you can ensure your application is using the correct encoding, which influences how Serilog writes to the console.
- C#:
This line, while not strictly part of Serilog, is crucial for ensuring that the data Serilog sends to the console is encoded correctly. Serilog uses
Console.OutputEncoding = System.Text.Encoding.UTF8;
Console.Out
, which respectsConsole.OutputEncoding
.
- C#:
- Test: Verify correct display of special characters.
-
Threats Mitigated:
- Data Misinterpretation (Low Severity): Prevents incorrect display.
- Log Injection (Low - Indirect): Helps prevent misinterpretations.
-
Impact:
- Data Misinterpretation: Risk significantly reduced.
- Log Injection: Minor indirect benefit.
-
Currently Implemented:
- Example:
Console.OutputEncoding = System.Text.Encoding.UTF8;
inProgram.cs
. Environments configured for UTF-8.
- Example:
-
Missing Implementation:
- Example: Add a test case to verify correct display of special characters in logs.