Skip to main content

A09 — Security Logging and Monitoring Failures

Insufficient logging and monitoring allows attackers to operate undetected. These rules detect swallowed exceptions, log injection vulnerabilities, and accidental logging of sensitive data.

OWASPA09001 — Empty catch block (swallowed exception)

PropertyValue
SeverityWarning
CategoryA09 Logging Failures

What it detects

catch blocks that contain no statements — exceptions are silently discarded without any logging or re-throwing.

Why it matters

Swallowed exceptions hide failures, making it impossible to detect attacks, diagnose problems, or trigger alerts. An empty catch is one of the most common causes of invisible security incidents.

❌ Non-compliant

try
{
ProcessPayment(order);
}
catch (Exception)
{
// silent failure — attacker can probe with no trace
}

✅ Compliant

try
{
ProcessPayment(order);
}
catch (Exception ex)
{
_logger.LogError(ex, "Payment processing failed for order {OrderId}", order.Id);
throw; // or return appropriate error response
}

OWASPA09002 — Catch block without logging

PropertyValue
SeverityWarning
CategoryA09 Logging Failures

What it detects

catch blocks that have statements but none of them involve a logging call (ILogger, Log., _logger., logger.).

❌ Non-compliant

catch (Exception ex)
{
return StatusCode(500, "Internal error");
// exception not logged anywhere
}

✅ Compliant

catch (Exception ex)
{
_logger.LogError(ex, "Unexpected error handling request");
return StatusCode(500, "Internal error");
}

OWASPA09003 — Log injection via taint

PropertyValue
SeverityWarning
CategoryA09 Logging Failures
TechniqueTaint analysis

What it detects

User-controlled data flowing directly into a logging call without sanitization. An attacker who can inject newlines into log messages can forge log entries and obscure evidence of an attack.

❌ Non-compliant

[HttpGet]
public IActionResult GetItem(string id)
{
// ❌ OWASPA09003: user input injected into log
_logger.LogInformation("Fetching item: " + id);
return Ok(_items[id]);
}

✅ Compliant

[HttpGet]
public IActionResult GetItem(string id)
{
// Use structured logging — the id is a parameter, not concatenated
_logger.LogInformation("Fetching item: {ItemId}", id);
return Ok(_items[id]);
}

Using structured logging (message templates with {Parameter}) prevents log injection because the value is stored separately from the message template in most log sinks.


OWASPA09004 — Sensitive data in log message

PropertyValue
SeverityWarning
CategoryA09 Logging Failures

What it detects

Log messages (string literals or interpolated strings passed to logging methods) that contain keywords suggesting sensitive data: password, secret, token, apikey, credential, ssn, creditcard.

Why it matters

Logging sensitive data (passwords, tokens, PII) writes them to log files, log aggregation systems, and monitoring dashboards — violating privacy regulations and creating new attack surfaces.

❌ Non-compliant

_logger.LogDebug($"User login attempt: username={username}, password={password}");

✅ Compliant

_logger.LogDebug("User login attempt: username={Username}", username);
// Never log the password