Why AI tools produce this: AI coding tools generate this anti-pattern by default, it appears in a large share of AI-written auth code.
Why this matters
The logged identifier is named like a credential (password, token, secret, apiKey, accessToken, refreshToken, privateKey, clientSecret, …) and the sink is a console.* or logger.* call. Logs are routinely written to files, shipped to aggregators (Datadog, Splunk, CloudWatch) and read by people who should never see the raw secret. This is a textbook credential leak.
Never log secrets. Redact or mask them before logging (token.slice(0, 4) + '…'), log a non-sensitive identifier instead (a user id, a key id), or drop the field entirely.
declare const token: string;declare const user: { id: string };declare const userId: string;declare const logger: { info: (...a: unknown[]) => void };export function statusMessages() { // ok: auth.flow.secret-in-log -- literal status text, no secret value console.log('password updated'); // ok: auth.flow.secret-in-log console.log('reset token sent'); // ok: auth.flow.secret-in-log console.log('login ok');}export function nonSecretIdentifiers() { // ok: auth.flow.secret-in-log -- member access, not a secret-named identifier console.log(user.id); // ok: auth.flow.secret-in-log logger.info({ userId });}export function redactedToken() { // ok: auth.flow.secret-in-log -- redacted, the argument is an expression not a bare secret identifier console.log('token prefix', token.slice(0, 4));}
Suppressing this rule
If a finding is a genuine false positive, scope the suppression to the exact line and leave a reason, never disable the rule project-wide. Disable directives are line-scoped by design.