Security and logging hygienehard5-8 years

A `LoginRequest` class overrides `toString()` so its `password` field prints as `[REDACTED]`. A teammate is confident this closes every path a password could leak through logging. Where are they wrong?

Overriding toString() protects every place that specific object is printed as itself — a whole-object log line, a debugger's watch window, a record printed by the JVM — but it protects nothing that reaches into the object's fields directly rather than going through that override. If any code builds a different string from the raw password field — a custom exception message, a validation error, a different method's log line that concatenates the field by name instead of the object — the redaction never runs, because that code path never calls the object's toString() at all. The fix that actually closes every path is wrapping the secret in its own small type whose toString() always says [REDACTED], so the protection travels with the value everywhere it's used, not just with the object that happens to hold it today.

The lesson behind it →
More on Security and logging hygiene