Course outline

Web Security / Advanced: assurance, supply chain, and recovery / Lesson 15

Security logging and safe error handling

Create useful evidence for authorized investigation without exposing credentials or converting alerts into unsupported conclusions.

About 4 min readContent reviewed
On this page

Lesson goals

  • Define bounded event and public-error contracts.
  • Distinguish observation, hypothesis, and confirmed impact.

Log to answer a concrete security question

Useful events can explain authentication changes, denied access, sensitive updates, file processing, and policy failures. Define what responders need to know: time, source, action, outcome, relevant opaque identifiers, and correlation context. Avoid collecting every request body or header merely because storage is available. Private notes, passwords, session values, reset links, and unnecessary personal information do not belong in ordinary diagnostics. Logs are sensitive assets with their own access, retention, integrity, and availability requirements. A large archive is not useful if responders cannot identify the relevant candidate, event, and decision safely.

Keep the evidence envelope small and explicit

The event is a fictional access denial with no real person or private payload. Its identifiers support a controlled investigation relationship rather than public disclosure. A real schema should validate event types, timestamps, sources, and field bounds, and preserve the difference between source time and collection time where needed. Structured logging can reduce ambiguity, but encoding a message as JSON does not itself make the source trustworthy or the storage tamper-resistant. Protect collection failures and dropped data as observable states; no events is not proof that no security issue occurred.

json A fictional bounded security event
{
  "event": "authorization-decision",
  "source": "synthetic-portal",
  "subjectRef": "lab-subject-a",
  "resourceRef": "lab-note-1",
  "operation": "edit-note",
  "outcome": "denied",
  "correlationRef": "lab-request-17"
}

The record is not sent or collected from a system. References are synthetic and contain no credentials. A production envelope needs trusted sources, access controls, retention, and verification of collection completeness.

Allowlist diagnostic fields rather than dumping objects

The pure function copies only three declared fields from synthetic input and verifies that an unrelated private-body field is absent. This demonstrates minimization at one boundary, not a general redaction engine. A real logger must validate types, control multiline content appropriately, and handle nested or transformed sensitive values according to policy. Removing a few familiar key names cannot guarantee secrets are gone. Review error trackers, browser traces, analytics, and support attachments as part of the same information flow. Keep diagnostic access limited to people with a justified need and expire records according to purpose.

python A complete offline diagnostic-field check
def diagnostic_fields(event):
    allowed = ("action", "outcome", "correlationRef")
    return {key: event[key] for key in allowed if key in event}

original = {"action": "edit-note", "outcome": "denied", "correlationRef": "lab-17", "privateBody": "synthetic-content-not-collected"}
summary = diagnostic_fields(original)
assert set(summary) == {"action", "outcome", "correlationRef"}
assert "privateBody" not in summary

The program reads only invented in-memory data and sends nothing. It shows one allowlist behavior, not detection of every secret or verification of a real logging platform. The original object is not modified.

Expose useful failures without unnecessary internals

A public error should support the legitimate next action without disclosing stack traces, query text, tokens, or private record existence beyond the intended policy. Keep detailed diagnostics behind controlled access and use an opaque correlation reference where helpful. Choose status and message behavior consistently with the API contract instead of relying on one universal error code to prevent information leakage. Error handling must not continue a protected mutation after reporting denial. Failed downstream jobs, retries, and partial results need explicit state semantics. A generic message alone does not establish safe rollback or correct transaction behavior.

Use evidence to test a hypothesis

A detection rule identifies patterns worth review; a count of failures alone does not confirm compromise. Correlate authorized context and preserve uncertainty about clocks, missing events, and source reliability. Test malformed, missing, delayed, and repeated event cases with benign fixtures. Verify collection and access paths in an authorized environment rather than triggering real abuse to make an alert fire. Route findings to an accountable owner with an approved runbook. Feedback from incidents should improve event quality and error behavior. Neither a quiet dashboard nor a local field-copy assertion proves the complete service is secure.

Common errors and fixes

An error response exposes a stack or token

Why it happens
Internal diagnostics are returned to an untrusted audience.
How to fix it
Separate public failure fields from protected diagnostics.
Prevent it next time
Test failure paths for data minimization.

No logs is called no incident

Why it happens
Collection health is assumed rather than verified.
How to fix it
Verify evidence completeness and preserve the observation gap.
Prevent it next time
Monitor missing and delayed evidence states.

A failed request leaves partial protected work

Why it happens
Error reporting is confused with transactional refusal.
How to fix it
Verify state and downstream effects under the operation contract.
Prevent it next time
Assert unchanged state where denial requires it.

Check your understanding

1. A log function omits a password key. Does that prove every diagnostic is safe?

Show worked solution

No. Sensitive data can appear in nested values, URLs, transformed fields, traces, and other channels. Minimize collection, validate the approved schema, and review the complete diagnostic flow rather than relying on one name-based filter.

2. A burst of failures precedes one success. What conclusion is justified?

Show worked solution

It is a pattern for authorized triage, not proof of compromise by itself. Review method, user intent, device and operation context, timing, and related outcomes while keeping unknowns explicit.

Key takeaways

  • Logs and errors are information-disclosure boundaries.
  • Minimize fields and verify collection completeness.
  • Signals support investigation rather than automatic certainty.

Official references