fix(deps): bump better-auth to 1.6.30 for GHSA-qq9h-g4jm-xgf3 - #292
fix(deps): bump better-auth to 1.6.30 for GHSA-qq9h-g4jm-xgf3#292kaseywright wants to merge 5 commits into
Conversation
Resolves a high-severity account takeover via pre-account hijacking on magic-link and email-OTP sign-in (vulnerable >=1.1.3 <1.6.22, fixed in 1.6.22). This repository is directly exposed: src/lib/auth.ts configures the magicLink plugin and an emailOTP sendOTP handler, and auth.service.ts calls signInMagicLink. 1.6.30 is the latest patch on the current minor line -- the smallest change that clears the advisory. 1.7.2 was evaluated and rejected: it hits the same peer conflict, so it buys nothing while adding a minor version bump to the authentication layer. The whole @better-auth/* family moves in lockstep, and better-call goes 1.3.5 -> 1.4.0. Note that better-call 1.4.0 no longer depends on zod at all, which makes the `overrides.better-call.zod` block in package.json a no-op. Left in place here; removing it is a separate change. Requires --legacy-peer-deps: @better-auth/drizzle-adapter declares peer @better-auth/core@^1.6.30, whose caret reaches into 1.7.x, so npm resolves core to 1.7.2 against better-auth's exact 1.6.30 dependency. That flag also prunes 10 dev-only vite peer entries from the lockfile, which is the bulk of the diff. Verified on node 24.14.0: tsc --noEmit clean, 473 tests pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JrPR3vYA5DwEwTiE4E2aJn
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe pull request pins ChangesBetter Auth dependency versions
Estimated code review effort: 1 (Trivial) | ~2 minutes Merge Risk: ⚪ Minimal · up to This change pins the authentication dependencies to the patched 1.6.30 release and updates the lockfile. No actionable merge-blocking risk remains after normal checks and review. Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Full details: Docstring CoverageExplanation No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (1 skipped: 1 unsupported.) ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
`npm install better-auth@1.6.30` preserved the existing caret prefix, producing ^1.6.30. That range extends to >=1.6.30 <2.0.0, so it admits 1.7.2 -- the very version this change evaluated and rejected for adding a minor bump to the authentication layer without clearing the advisory any better. The floor was never the problem: ^1.6.30 already prevented regression below the vulnerable 1.6.22 boundary. The problem was upward drift into an untested minor, which is not hypothetical here because CI installs with `npm install` rather than `npm ci` and rewrites the lockfile as it goes. Exact pins also match what the other 33 direct dependencies do. Scoped deliberately to these three. The remaining caret specs (@aws-sdk/*, bcryptjs) are a separate decision -- the AWS SDK's near-daily patch cadence is a real argument for floating that these packages do not have. No resolved version changed: only the three specification strings. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JrPR3vYA5DwEwTiE4E2aJn
The lockfile was generated with --legacy-peer-deps, which makes npm skip peer resolution and omit 10 vite/babel peer entries (@vue/compiler-*, @babel/parser, entities, estree-walker) from the tree. Dockerfile.dev runs plain `npm ci`, which recomputes the expected tree *with* peers, finds those entries missing, and fails with EUSAGE. This broke the api and worker image builds, so `./fluent.sh up` could not start the ecosystem. The flag was not needed. Regenerating without it resolves cleanly and pins @better-auth/core to 1.6.30 throughout, matching better-auth's exact dependency rather than hoisting 1.7.2. better-auth, @better-auth/core, @better-auth/drizzle-adapter and @better-auth/passkey all remain at 1.6.30, so GHSA-qq9h-g4jm-xgf3 stays cleared. Verified `npm ci` installs 885 packages, the full stack builds and comes up healthy, and /api/auth/get-session and /api/auth/sign-in/magic-link both return 200 against better-auth 1.6.30. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JtDeMTGVhfrqoV5ExVUm2d
Clears the last open advisory, and the only high-severity one in the repo.
GHSA-qq9h-g4jm-xgf3 — Better Auth: account takeover via pre-account hijacking on magic-link and email-OTP sign-in. Vulnerable
>= 1.1.3, < 1.6.22; fixed in 1.6.22.This one is directly exploitable here
Not a theoretical transitive risk — the app uses both affected sign-in paths:
src/lib/auth.ts:152configures themagicLinkplugin with asendMagicLinkhandlersrc/lib/auth.ts:134implementssendOTPfor email OTPsrc/lib/services/auth/auth.service.ts:129callsapi.signInMagicLink(...)It has been open since the fix shipped, because PR #242 was closed on 2026-07-27 and Dependabot then stopped offering the release.
Why 1.6.30, not 1.7.2
1.6.30 is the newest patch on the current minor line — the smallest change that clears the advisory. I evaluated 1.7.2 and rejected it: it hits the same peer conflict (below), so it buys nothing on that front while adding a minor-version bump to the authentication layer.
Pinned exactly, not with a caret
npm installpreserved the existing caret prefix and wrote^1.6.30. That range is>=1.6.30 <2.0.0, so it admits 1.7.2 — the version this PR evaluated and rejected just above. The specs are now exact1.6.30, which also matches what the other 33 direct dependencies do.The floor was never the issue:
^1.6.30already prevented regression below the vulnerable<1.6.22boundary, so the advisory could not return either way. The issue was upward drift into an untested minor of the auth layer — not hypothetical, since CI installs withnpm installrather thannpm ciand rewrites the lockfile as it goes.Scoped to these three. The remaining caret specs (
@aws-sdk/*,bcryptjs) are a separate decision.Why
--legacy-peer-depswas needed@better-auth/drizzle-adapter@1.6.30declarespeer @better-auth/core@"^1.6.30". That caret reaches into 1.7.x, so npm resolves core to 1.7.2 whilebetter-auth@1.6.30pins core to exactly1.6.30. Unresolvable without the flag — and it reproduces identically at 1.7.2, so it is structural, not version-specific.The flag has a side effect: it makes npm ignore
peerDependencies, which prunes 10 dev-only vite peer entries (@vue/compiler-*,@babel/*,entities,estree-walker) and flips 188devOptional→devflags. That accounts for most of the diff. The 15 substantive version changes are the@better-auth/*family plusbetter-call1.3.5→1.4.0,@better-fetch/fetch,@noble/hashes,rou3,set-cookie-parser.Worth flagging: an override is now dead config
better-call@1.4.0no longer depends on zod at all — its dependencies are@better-auth/utils,@better-fetch/fetch,rou3,set-cookie-parser. That makes this block inpackage.jsona no-op:Left in place deliberately — removing it is a separate change with its own reasoning, not something to slip into a security fix.
Verification
Node 24.14.0.
tsc --noEmitclean. 473 tests pass across 53 files, includingsrc/lib/auth.test.tsandsrc/lib/services/auth/auth.service.test.ts.Worth a manual smoke of a magic-link sign-in before merge, given the change is to that exact code path.
🤖 Generated with Claude Code
https://claude.ai/code/session_01JrPR3vYA5DwEwTiE4E2aJn
Summary by CodeRabbit
1.6.30for more consistent builds and deployments.