v0.14 is out: a mobile auth pack for Swift/iOS and Android, catching insecure token storage, cleartext traffic, and OAuth in embedded WebViews. Read more →
HIGH AI PREVALENCE: MEDIUM auth.flow.basic-auth-in-log

HTTP Basic credentials flow into a logging call (console.* or logger.*).

Why AI tools produce this: AI coding tools produce this regularly, typically when prompted for a shortcut or a quick fix.

Why this matters

The basic-auth package returns the decoded { name, pass } for the request, and the Proxy-Authorization header carries base64-encoded user:password just like Authorization does. Logs are written to files, shipped to aggregators (Datadog, Splunk, CloudWatch) and read by people and systems that should never see live credentials. The base64 is trivially reversible, so a logged Basic header or a logged creds.pass is a plaintext password leak (CWE-532).

Never log the raw credential. Redact or mask it before logging, log a non-sensitive identifier instead (the username alone, a user id), or drop the field entirely.

VULNERABLE
vulnerable.ts
import type { Request, Response } from 'express';
import auth from 'basic-auth';

declare const logger: {
  info: (...a: unknown[]) => void;
  debug: (...a: unknown[]) => void;
  error: (...a: unknown[]) => void;
};

// basic-auth parse result logged directly — leaks the decoded password.
export function login(req: Request, res: Response): void {
  const credentials = auth(req);
  // ruleid: auth.flow.basic-auth-in-log
  console.log('login attempt', credentials?.name, credentials?.pass);
  res.sendStatus(200);
}

// basic-auth .pass assigned to a local, then logged via a logger (indirection).
export function verify(req: Request, res: Response): void {
  const pw = auth(req)?.pass;
  // ruleid: auth.flow.basic-auth-in-log
  logger.debug('verifying', pw);
  res.sendStatus(200);
}

// Proxy-Authorization header logged on a proxy auth failure.
export function proxyAuth(req: Request, res: Response): void {
  // ruleid: auth.flow.basic-auth-in-log
  console.error('proxy auth failed for', req.headers['proxy-authorization']);
  res.sendStatus(407);
}

// Proxy-Authorization via req.get(...), interpolated into a warning logger.
export function proxyGet(req: Request, res: Response): void {
  const header = req.get('proxy-authorization');
  // ruleid: auth.flow.basic-auth-in-log
  logger.info(`upstream proxy creds: ${header}`);
  res.sendStatus(200);
}
SAFE
safe.ts
import type { Request, Response } from 'express';
import auth from 'basic-auth';

declare const logger: {
  info: (...a: unknown[]) => void;
  debug: (...a: unknown[]) => void;
  error: (...a: unknown[]) => void;
};

declare function redact(v: unknown): string;

// Safe: log only the non-sensitive username, never the password.
export function login(req: Request, res: Response): void {
  const credentials = auth(req);
  // ok: auth.flow.basic-auth-in-log
  console.log('login attempt for user', credentials?.name);
  res.sendStatus(200);
}

// Safe: the password is redacted before it reaches the log sink.
export function verify(req: Request, res: Response): void {
  const pw = auth(req)?.pass;
  // ok: auth.flow.basic-auth-in-log
  logger.debug('verifying', redact(pw));
  res.sendStatus(200);
}

// Safe: the Proxy-Authorization header is masked (first chars only) before
// logging, so the live credential never reaches the log.
export function proxyAuth(req: Request, res: Response): void {
  const header = req.get('proxy-authorization') ?? '';
  // ok: auth.flow.basic-auth-in-log
  console.error('proxy auth header prefix', header.slice(0, 6));
  res.sendStatus(407);
}

// Safe: a constant status message — no credential involved.
export function status(_req: Request, res: Response): void {
  // ok: auth.flow.basic-auth-in-log
  logger.info('proxy authentication required');
  res.sendStatus(407);
}

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.

// oauthlint-disable-next-line auth.flow.basic-auth-in-log -- <reason>

References

https://cwe.mitre.org/data/definitions/532.html ↗https://www.npmjs.com/package/basic-auth ↗https://owasp.org/API-Security/editions/2023/en/0xa8-security-misconfiguration/ ↗