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 →
MEDIUM AI PREVALENCE: HIGH auth.cookie.no-secure

A cookie that looks like a session or auth cookie is being set WITHOUT the Secure flag.

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 browser will happily send it over plain HTTP, which means a network attacker (open Wi-Fi, malicious proxy, downgrade attack) can capture it.

Add { secure: true } to the cookie options. If you absolutely need to set Secure-less cookies in dev, gate it on NODE_ENV !== 'production'.

VULNERABLE
vulnerable.ts
import type { Response } from 'express';

export function loginBad(res: Response, token: string) {
  // ruleid: auth.cookie.no-secure
  res.cookie('session', token, { httpOnly: true, sameSite: 'lax' });
}

export function loginBad2(res: Response, jwt: string) {
  // ruleid: auth.cookie.no-secure
  res.cookie('auth_token', jwt);
}

export function loginBad3(res: Response, token: string) {
  // ruleid: auth.cookie.no-secure -- secure explicitly disabled
  res.cookie('session', token, { httpOnly: true, secure: false });
}
SAFE
safe.ts
import type { Response } from 'express';

// ok: auth.cookie.no-secure
export function loginGood(res: Response, token: string) {
  res.cookie('session', token, {
    httpOnly: true,
    secure: true,
    sameSite: 'strict',
  });
}

// ok: auth.cookie.no-secure -- conditional secure (the recommended dev gate) must not be flagged
export function loginConditional(res: Response, token: string) {
  res.cookie('session', token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'strict',
  });
}

// ok: auth.cookie.no-secure -- "preferences" is not an auth cookie
export function setPrefs(res: Response, value: string) {
  res.cookie('preferences', value, { httpOnly: false });
}

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.cookie.no-secure -- <reason>

References

https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.2.5 ↗