Address CodeQL findings on the OIDC auth flow

- Open redirect / client-side XSS (app-base.js): the post-login `redirect`
  read from the URL fragment was assigned straight to window.location. Add a
  same-origin guard (safeInternalPath) that rejects absolute URLs,
  protocol-relative "//host"/"/\\host", and scheme targets like
  "javascript:". Apply it in consumeTokenFragment and logInRedirect.
- Server-side defense in depth: sanitize `redirect` when storing OidcState
  and when building the callback fragment (utils/safe_redirect.js, shared +
  unit-tested).
- Missing rate limiting: throttle the unauthenticated auth endpoints
  (/login, /oidc/start, /oidc/callback) with express-rate-limit (60/IP/15m).
  Set `trust proxy: 1` so req.ip reflects the real client behind OpenResty.

Adds test/unit/safe_redirect.test.js; unit suite 77 pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 13:22:12 -04:00
parent 08bef1bd00
commit cff816fa06
7 changed files with 137 additions and 10 deletions
+5
View File
@@ -7,6 +7,11 @@ const express = require('express');
// Set up the express app.
const app = express();
// The app always runs behind the OpenResty reverse proxy (a single hop) which
// sets X-Real-IP / X-Forwarded-For. Trust that one proxy so req.ip reflects the
// real client — needed for correct per-client rate limiting on /api/auth.
app.set('trust proxy', 1);
// Hold list of functions to run when the server is ready
app.onListen = [];