Skip to content

fix(deps): bump better-auth to 1.6.30 for GHSA-qq9h-g4jm-xgf3 - #292

Open
kaseywright wants to merge 5 commits into
mainfrom
fix/better-auth-ghsa-qq9h
Open

fix(deps): bump better-auth to 1.6.30 for GHSA-qq9h-g4jm-xgf3#292
kaseywright wants to merge 5 commits into
mainfrom
fix/better-auth-ghsa-qq9h

Conversation

@kaseywright

@kaseywright kaseywright commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Clears the last open advisory, and the only high-severity one in the repo.

GHSA-qq9h-g4jm-xgf3Better 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:152 configures the magicLink plugin with a sendMagicLink handler
  • src/lib/auth.ts:134 implements sendOTP for email OTP
  • src/lib/services/auth/auth.service.ts:129 calls api.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 install preserved 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 exact 1.6.30, which also matches what the other 33 direct dependencies do.

The floor was never the issue: ^1.6.30 already prevented regression below the vulnerable <1.6.22 boundary, 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 with npm install rather than npm ci and rewrites the lockfile as it goes.

Scoped to these three. The remaining caret specs (@aws-sdk/*, bcryptjs) are a separate decision.

Why --legacy-peer-deps was needed

@better-auth/drizzle-adapter@1.6.30 declares peer @better-auth/core@"^1.6.30". That caret reaches into 1.7.x, so npm resolves core to 1.7.2 while better-auth@1.6.30 pins core to exactly 1.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 188 devOptionaldev flags. That accounts for most of the diff. The 15 substantive version changes are the @better-auth/* family plus better-call 1.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.0 no longer depends on zod at all — its dependencies are @better-auth/utils, @better-fetch/fetch, rou3, set-cookie-parser. That makes this block in package.json a no-op:

"overrides": { "better-call": { "zod": "$zod" } }

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 --noEmit clean. 473 tests pass across 53 files, including src/lib/auth.test.ts and src/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

  • Chores
    • Updated authentication-related dependencies to exact version 1.6.30 for more consistent builds and deployments.

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
@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6d2c3355-ed98-4937-aa26-acc13af76ae6

📥 Commits

Reviewing files that changed from the base of the PR and between d5a969c and e4d53bc.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (1)
  • package.json

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The pull request pins @better-auth/drizzle-adapter, @better-auth/passkey, and better-auth to exact version 1.6.30 values in package.json.

Changes

Better Auth dependency versions

Layer / File(s) Summary
Pin Better Auth dependency versions
package.json
Three Better Auth dependencies change from caret ranges to exact version 1.6.30 values.

Estimated code review effort: 1 (Trivial) | ~2 minutes

Merge Risk: ⚪ Minimal · up to e4d53

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: anumonachan, henrique221

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the dependency update to Better Auth version 1.6.30 and states its security purpose. It matches the main changeset.
Docstring Coverage ✅ Passed 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…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

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)
  • Create PR with unit tests
  • Commit unit tests in branch fix/better-auth-ghsa-qq9h

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

kaseywright and others added 4 commits August 27, 2026 16:11
`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
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.

2 participants