guest@websec: ~/websec/21-logging-and-incident-response — zsh — 100×40 by SaKKo ENTH code:

guest@websec ~ % man 21-logging-and-incident-response

21 · Logging, Alerting and Incident Response

Every defense eventually fails somewhere. What matters is how fast you notice and how well you respond.

21.1 What to log

Log security events with who, what, when, from where and result.

log these

  • logins: success, failure, lockout, logout
  • password, email and MFA changes; password resets
  • authorization failures (403s, policy denials)
  • CSRF token failures, rate-limit hits
  • admin actions and permission changes
  • high-value transactions, large exports
  • input validation failures that look like attacks
  • CSP violation reports

never log these

  • passwords (even wrong ones: they're often a real password with a typo)
  • session ids, API keys, tokens, reset links
  • full card numbers, CVVs
  • secrets from config or environment
  • more personal data than you need (privacy laws apply to logs too)
Rails logs requests (with secrets filtered) but not security events like logins or denials. Add those yourself, as structured JSON.
# a tiny security-event helper
# (assumes Current has request_id and ip, set in a before_action)
module SecurityLog
  def self.event(name, **data)
    Rails.logger.info({ event: name, at: Time.now.utc.iso8601,
      user_id: Current.user&.id, request_id: Current.request_id, ip: Current.ip, **data }.to_json)
  end
end

SecurityLog.event("login.failure", email_hash: Digest::SHA256.hexdigest(email.downcase))
SecurityLog.event("authz.denied", policy: "OrderPolicy#refund?", order_id: order.id)
SecurityLog.event("admin.role_changed", target_id: user.id, from: "member", to: "admin")

21.2 Log injection

A newline in user input can fake a whole log line, like "admin logged in". Log as JSON and the input stays in its box.

sim: forging a log lineusername typed at login

logger.info "login.failure user=#{username}"

structured JSON log

21.3 Alerting: logs nobody reads don't count

Breaches often sit in the logs for months, unseen. Turn the key signals into alerts someone owns: failed-login spikes, new admins, big exports. Keep them few or people tune them out.

sim: tune an alertfailed logins per minute, last hour

21.4 Protecting the logs themselves

  • Ship logs off the app servers to a central system (attackers delete local logs).
  • Restrict who can read them; they contain personal data.
  • Make them append-only or tamper-evident where it matters (audit trails).

21.5 Incident response

Steps: detect, analyze, contain, fix, recover, learn. Write a one-page runbook now: who to call, how to rotate secrets, how to log everyone out. Under Thailand's PDPA (and the EU's GDPR) you have 72 hours from discovering a personal-data breach to notify the regulator, unless it's unlikely to harm anyone. High-risk breaches must also be reported to the people affected.

drill: put the response in orderclick the steps in the order you'd do them