← Back to OWASP Top 10 for Web Applications
A09:20214 min read read

Security Logging and Monitoring Failures

Log security events with enough context to detect and respond — without leaking secrets in log output.

URL: trusteed.io/academy/web-security/security-logging-and-monitoring-failures

Security Logging and Monitoring Failures occur when an application doesn't generate sufficient logs to detect and investigate a security incident, or generates logs that nobody actually monitors — meaning breaches go undetected for extended periods, sometimes discovered only when a third party (a customer, a law enforcement agency, or the attacker's own public disclosure) reports it. This category is unusual on the list because the failure isn't visible in the vulnerability itself — it's visible in how long an attack goes unnoticed afterward.

What Is This Category?

The category covers several distinct gaps: insufficient logging — authentication attempts, access control failures, and server-side validation failures that aren't logged at all, leaving no record for later investigation; logs that exist but are never reviewed — generating log data is only useful if something (a human analyst or an automated detection system) actually examines it; logs that lack enough context — a log entry recording "login failed" without a timestamp, source IP, or username provides little forensic value; and no alerting on suspicious patterns — a spike in failed logins or a burst of 403 responses from a single source should trigger an alert, not silently accumulate in a log file no one is watching.

Why AI Coding Assistants Get This Wrong

Logging is frequently treated as a debugging convenience during development — console.log() statements added to understand what's happening, then either left in unstructured or stripped out entirely before what's considered "the real work" (the feature logic) is complete. Security-relevant logging — specifically recording authentication events, authorization failures, and input validation failures in a structured, consistently-formatted way — requires being asked for explicitly, since it's not a natural byproduct of implementing a feature's primary function the way basic debug output is.

Vulnerable Pattern

// No logging of authentication failures at all — failed attempts leave no trace
app.post('/login', async (req, res) => {
  const user = await authenticateUser(req.body.email, req.body.password);
  if (!user) {
    return res.status(401).json({ error: 'Invalid credentials' }); // silent failure, no record
  }
  res.json({ token: generateToken(user) });
});

// Access control failure — logged with no useful context, if at all
app.use('/api/admin', (req, res, next) => {
  if (req.user.role !== 'admin') return res.status(403).send('Forbidden');
  next();
});

Secure Pattern

const logger = require('./logger'); // structured logger (e.g., pino, winston) writing to a central sink

app.post('/login', async (req, res) => {
  const user = await authenticateUser(req.body.email, req.body.password);
  if (!user) {
    logger.warn({
      event: 'auth_failure',
      email: req.body.email,
      ip: req.ip,
      timestamp: new Date().toISOString(),
    });
    return res.status(401).json({ error: 'Invalid credentials' });
  }
  logger.info({ event: 'auth_success', userId: user.id, ip: req.ip });
  res.json({ token: generateToken(user) });
});

app.use('/api/admin', (req, res, next) => {
  if (req.user.role !== 'admin') {
    logger.warn({
      event: 'access_control_failure',
      userId: req.user.id,
      attemptedResource: req.originalUrl,
      ip: req.ip,
      timestamp: new Date().toISOString(),
    }); // structured, alertable, and correlatable across a burst of similar events
    return res.status(403).json({ error: 'Forbidden' });
  }
  next();
});

The secure version differs primarily in structure and consistency — every security-relevant event includes enough context (who, what, when, from where) to reconstruct an incident timeline later, and is formatted consistently enough for automated alerting to key off of it (e.g., alert if auth_failure events from a single IP exceed a threshold within a short window).

Copy-Paste Rules for Cursor, Claude Code, and Codex

---
description: Security logging and monitoring — structured, actionable event logging
alwaysApply: true
---

# Security Logging Rules

- Log every authentication attempt (success and failure), access control
  failure, and server-side input validation failure with structured,
  consistent fields: event type, timestamp, relevant identity (user ID or
  attempted email), source IP, and the resource involved.
- Never log sensitive data itself (passwords, full tokens, credit card
  numbers) even in a security event log — log that an event occurred, not
  the sensitive payload involved.
- Use a structured logging format (JSON or equivalent), not free-text
  string concatenation, so logs can be reliably parsed, searched, and
  correlated by automated tooling.
- Ensure security-relevant logs are sent to a centralized, tamper-resistant
  log store rather than only written to local files that could be deleted
  or altered by an attacker who gains access to the host.
- Recommend or implement basic alerting thresholds for security events
  where feasible (e.g., repeated authentication failures from a single
  source in a short window) rather than assuming logs alone will be
  manually reviewed in time to matter.
- When generating authentication, authorization, or input-validation code,
  include structured security event logging in the same pass — do not
  treat logging as a separate, later addition.

Verification Checklist

  • Authentication attempts (success and failure) are logged with structured, consistent fields
  • Access control failures are logged with enough context to investigate later
  • Logs never contain sensitive data (passwords, full tokens, PII beyond what's necessary)
  • Logs are sent to a centralized store, not only local files on the originating host
  • Alerting thresholds exist for suspicious patterns (repeated auth failures, bursts of access denials)
  • Log review or automated monitoring is an active, ongoing practice, not a passive data store nobody checks
  • Enriched, noise-filtered monitoring reduces false positives so genuine incidents surface faster — see Trusteed's threat intelligence platform and the SOC glossary entry for how this connects to broader monitoring operations

Frequently asked questions

Does having logs automatically mean an organization can detect a breach?

No — logs are necessary but not sufficient. Detection requires something (a person or an automated system) actively reviewing or alerting on that log data. A comprehensive log that nobody ever queries provides forensic value after the fact at best, and no detection capability at all in the moment.

Why shouldn't sensitive data be included in security logs?

Because logs are themselves a target — if an attacker gains access to log storage, logs containing passwords, full session tokens, or unmasked payment data become an additional breach in their own right, compounding the original incident rather than just documenting it.

How does this category relate to Threat Intelligence and SOC operations?

Logging failures directly undermine SOC effectiveness — a Security Operations Center can only detect and respond to what's actually being logged and surfaced as an alert. See [What Is a Security Operations Center (SOC)?](https://trusteed.io/academy/glossary/security-operations-center) and [What Is Threat Intelligence?](https://trusteed.io/academy/glossary/threat-intelligence) for how logging feeds into the broader detection and response pipeline.