Browse Source

fix(auth): surface OIDC state errors instead of failing silently

- When OIDC state handle is not found, callback now returns an Error
  instead of (null, undefined, undefined), which caused passport to
  fail silently with no feedback to the user or logs.

- When OIDC state has expired, callback now returns a descriptive Error
  so the user gets a meaningful message instead of a silent redirect
  failure.

- Replaced Math.random()-based handle generation with
  randomBytes(32) from node:crypto. The previous implementation was
  not cryptographically secure despite the comment claiming otherwise,
  making state handles potentially predictable.

Fixes #7716
pull/7797/head
Shreya 6 days ago
parent
commit
286e5d467d
  1. 30
      apps/api/src/app/auth/oidc-state.store.ts

30
apps/api/src/app/auth/oidc-state.store.ts

@ -1,5 +1,6 @@
import type { Request } from 'express';
import ms from 'ms';
import { randomBytes } from 'node:crypto'; // ADD THIS LINE
import type {
SessionStore,
SessionStoreCallback,
@ -66,14 +67,21 @@ export class OidcStateStore implements SessionStore {
const data = this.stateMap.get(handle);
if (!data) {
return callback(null, undefined, undefined);
}
return callback(
new Error('Invalid OIDC state parameter'),
undefined,
undefined
);
}
if (Date.now() - data.timestamp > this.STATE_EXPIRY_MS) {
// State has expired
this.stateMap.delete(handle);
return callback(null, undefined, undefined);
}
if (Date.now() - data.timestamp > this.STATE_EXPIRY_MS) {
this.stateMap.delete(handle);
return callback(
new Error('OIDC state has expired, please try again'),
undefined,
undefined
);
}
// Remove state after verification (one-time use)
this.stateMap.delete(handle);
@ -106,10 +114,6 @@ export class OidcStateStore implements SessionStore {
* Generate a cryptographically secure random handle
*/
private generateHandle() {
return (
Math.random().toString(36).substring(2, 15) +
Math.random().toString(36).substring(2, 15) +
Date.now().toString(36)
);
}
return randomBytes(32).toString('hex');
}
}

Loading…
Cancel
Save