Skip to content

Fix an open redirect and update vulnerable dependencies - #27

Merged
RonnyB71 merged 2 commits into
mainfrom
fix/security-open-redirect-and-deps
Nov 1, 2026
Merged

RonnyB71 merged 2 commits into
mainfrom
fix/security-open-redirect-and-deps

Conversation

@RonnyB71

@RonnyB71 RonnyB71 commented Nov 1, 2026

Copy link
Copy Markdown
Collaborator

Fixes the two most urgent findings from a security review of the login (#23).

Open redirect after password login

/logg-inn?redirect=%2F%09%2Fevil.example sent someone who logged in with a password to http://evil.example/.

Cause: the check rejected // and \, but not a tab. Browsers drop tabs and newlines from a Location header, so /<tab>/evil.example turns into //evil.example.

Fix: the target is now resolved with the URL parser, as a browser would resolve it, and must be on the same origin. Only its path, query and fragment are used.

Tests: added cases for tabs, newlines, backslashes and javascript:, plus same-site targets.

The Entra ID path in the CMS (safeRedirect in src/cms/src/auth/oidc.ts) wasn't affected, because it already compared origins after new URL().

Vulnerable dependencies

pnpm audit --prod went from 4 critical, 10 high to 0 critical, 2 high.

Package From → to Why
next (+ eslint-config-next) 16.3.3 → 16.4.3 Two unauthenticated RCEs (Image Optimization with SVG, use cache), RCE in next/og, SSRF, DoS
sharp 0.35.4 → 0.35.5 librsvg vulnerability; also overridden for Astro, which pulls in its own copy
undici (via payload) 7.29.1 → 7.30.1, override TLS validation bypass, cache poisoning, DoS
dompurify (via the admin panel's Monaco editor) 3.4.15 → 3.4.17, override Sanitizer bypasses

The overrides are in pnpm-workspace.yaml. Remove each one once Payload or Astro depends on a fixed version itself.

Left as they are:

  • happy-dom (2 high): it comes from Payload's rich text package and is only used when converting HTML to Lexical, which Saman doesn't do. The fix is a major version (21), so I'm waiting for Payload to update it rather than forcing it.
  • esbuild (moderate), via drizzle-kit: only a problem for esbuild's own dev server, which isn't used.
  • deepmerge (low).

Other

  • Flaky e2e test: the admin "list view" test now accepts a query string in the URL. Payload's list view sometimes adds ?depth=1&limit=10 after loading, which made the test fail intermittently after the upgrade.

Tests

  • pnpm lint: no errors or warnings.
  • pnpm test: CMS 28 passed, web 15 passed.
  • pnpm test:e2e: 9 passed.
  • pnpm --filter cms build succeeds on Next.js 16.4.3.

🤖 Generated with Claude Code

RonnyB71 and others added 2 commits November 1, 2026 18:47
/logg-inn checked the redirect target as a string, so
"/<tab>/evil.example" got through: browsers drop the tab and follow it
to //evil.example. The target is now resolved with the URL parser, as a
browser would, and must be on the same origin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Next.js 16.3.3 has two unauthenticated remote code execution
vulnerabilities, among others; 16.4.3 fixes them. sharp, undici and
DOMPurify come in through Astro and Payload at vulnerable versions, so
pnpm overrides lift them to fixed ones until those packages do.

The admin list view e2e test now allows the query the list view may add
to the URL once loaded, which made it flaky.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@RonnyB71
RonnyB71 merged commit c9f9020 into main Nov 1, 2026
6 checks passed
@RonnyB71
RonnyB71 deleted the fix/security-open-redirect-and-deps branch November 1, 2026 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant