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: MEDIUM auth.session.no-regeneration

The user is marked as logged in without first regenerating the session id.

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 identity is written onto the session (req.session.user = ..., req.session.userId = ..., etc.) before the session id is rotated. This opens the door to session-fixation attacks: an attacker who plants a known session id in the victim's browser before login retains access after authentication succeeds.

Call req.session.regenerate(cb) (or your framework's equivalent) between authenticating the credentials and writing the user identity onto the session.

OWASP ASVS V3.2.1: "The session id must be regenerated on authentication".

VULNERABLE
vulnerable.ts
interface Req {
  session: {
    user?: unknown;
    userId?: number;
    user_id?: number;
    uid?: number;
    authenticated?: boolean;
    isAuthenticated?: boolean;
    regenerate?: (cb: (err?: Error) => void) => void;
  };
}

export function loginBad(req: Req, user: { id: number; email: string }) {
  // ruleid: auth.session.no-regeneration
  req.session.user = user;
}

export function loginBad2(req: Req, id: number) {
  // ruleid: auth.session.no-regeneration
  req.session.userId = id;
}

export function loginBad3(req: Req) {
  // ruleid: auth.session.no-regeneration
  req.session.authenticated = true;
}
SAFE
safe.ts
interface Req {
  session: {
    user?: unknown;
    userId?: number;
    regenerate: (cb: (err?: Error) => void) => void;
  };
}

// ok: auth.session.no-regeneration -- callback form
export function loginGood(req: Req, user: { id: number; email: string }) {
  req.session.regenerate((err) => {
    if (err) throw err;
    req.session.user = user;
  });
}

// ok: auth.session.no-regeneration -- promisified async form (regenerate first)
export async function loginGoodAsync(req: Req, user: { id: number; email: string }) {
  await new Promise<void>((resolve) => req.session.regenerate(() => resolve()));
  req.session.user = user;
}

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.session.no-regeneration -- <reason>

References

https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html#renew-the-session-id-after-any-privilege-level-change ↗