v1.6.16

ruixenui/ruixen.comv1.6.16Jun 10, 2026by better-release[bot]

AI Summary

A comprehensive bug fix release focusing on security and stability, addressing critical vulnerabilities in SIWE verification, OAuth token handling, and SSO replay attacks while improving session management and permission enforcement.

Key Highlights

  • Fixed SIWE signature binding to server state to prevent replay
  • Fixed PayPal and Google ID token verification using JWKS
  • Fixed SSO replay attacks and SSRF protection
  • Fixed API key verification to prevent concurrent state issues
  • Fixed JWKS cache cross-contamination between issuers

New Features

  • Enhanced OAuth provider security
  • Improved SSO provider isolation
  • Fixed Reddit provider email collision bug
  • Fixed Facebook token verification
  • Fixed email sign-in Origin header validation

Full Release Notes

## `better-auth`

### Bug Fixes

- Fixed SIWE verification to bind the signed message to server state before creating a session, preventing acceptance of signatures produced for a different message, earlier nonce, or unrelated domain.
- Fixed PayPal ID token verification to validate the signature, issuer, audience, expiration, and nonce against PayPal's JWKS (RS256) or client secret (HS256), rejecting tokens that pass only structural checks.
- Fixed Google `hd` (hosted domain) enforcement to verify the `hd` claim on the verified ID token and callback profile, preventing accounts outside the configured Workspace domain from signing in.
- Fixed `verifyAccessToken` remote introspection to reject tokens with a missing or mismatching `aud` claim; set `remoteVerify.allowMissingAudience: true` to permit tokens where the introspection response legitimately omits `aud`.
- Fixed the admin plugin to enforce permissions on role, ban, and email fields in `/admin/create-user` and `/admin/update-user`, and prevent `data` from overriding protected fields. ([#9974](https://github.com/better-auth/better-auth/pull/9974))
- Fixed email sign-in and sign-up to validate `Origin` and `Referer` headers against `trustedOrigins` even when requests carry no cookies. ([#9973](https://github.com/better-auth/better-auth/pull/9973))
- Fixed `/update-session` to reject plugin-managed fields (`activeOrganizationId`, `activeTeamId`, `impersonatedBy`) with a 400 error; use their dedicated endpoints to change these values. ([#9965](https://github.com/better-auth/better-auth/pull/9965))
- Fixed `/update-session` and account token routes to immediately reject deleted sessions when cookie cache is enabled alongside database or secondary storage. ([#9967](https://github.com/better-auth/better-auth/pull/9967))
- Fixed `/refresh-token` to only trust the account cookie when its `userId`, `providerId`, and `accountId` match the resolved session user.
- Fixed generic OAuth sign-in to reject sign-ins when no account ID can be resolved from the provider response, preventing account collisions on providers that omit `sub`.
- Fixed `createInvitation` and `acceptInvitation` to validate that all requested team IDs belong to the invitation's organization, preventing cross-organization team membership.
- Fixed the JWKS cache to be scoped per verification source with a TTL, preventing key cross-contamination when verifying tokens against multiple issuers simultaneously.
- Fixed the Reddit provider to stop storing `oauth_client_id` as the user email, preventing all users of the same app from sharing a single email address; a synthetic per-user address is now used when no real email is provided via `mapProfileToUser`.
- Fixed Facebook token verification to validate tokens against the configured app via the `debug_token` endpoint, requiring `is_valid`, a matching `app_id`, and a client secret for direct sign-in.

For detailed changes, see [`CHANGELOG`](https://github.com/better-auth/better-auth/blob/1a3c8c478a94a7a2ddd1f0b62250b51f4fa0583f/packages/better-auth/CHANGELOG.md)

## `@better-auth/oauth-provider`

### Bug Fixes

- Fixed the token endpoint to enforce per-client grant types, preventing clients registered only for `authorization_code` from requesting `client_credentials` tokens.
- Fixed `/oauth2/continue` to derive post-login gate completion from a server-issued session marker rather than the client-submitted `postLogin` flag.
- Fixed token introspection to require an `azp` claim and a valid client on JWT access tokens, preventing session JWTs from being reported as active access tokens.

For detailed changes, see [`CHANGELOG`](https://github.com/better-auth/better-auth/blob/1a3c8c478a94a7a2ddd1f0b62250b51f4fa0583f/packages/oauth-provider/CHANGELOG.md)

## `@better-auth/sso`

### Bug Fixes

- Fixed SAML `AuthnRequest` handling to consume the request atomically, preventing replay attacks on concurrent requests. ([#9972](https://github.com/better-auth/better-auth/pull/9972))
- Fixed SSO provider IDs to be isolated from the OAuth/social account-linking namespace, preventing unintended account linking when an SSO provider ID matches a trusted OAuth provider name.
- Fixed OIDC endpoint validation to reject server-side requests resolving to non-publicly-routable addresses, protecting against SSRF on token, userinfo, and JWKS endpoints.

For detailed changes, see [`CHANGELOG`](https://github.com/better-auth/better-auth/blob/1a3c8c478a94a7a2ddd1f0b62250b51f4fa0583f/packages/sso/CHANGELOG.md)

## `@better-auth/api-key`

### Bug Fixes

- Fixed API key verification to persist only the fields it mutates rather than the full record, preventing concurrent disables, permission changes, or expiry updates from being reverted by an in-flight verification.
- Fixed `/api-key/create` to verify the session against the authoritative store with `disableCookieCache: true`, preventing revoked sessions from being accepted within the cookie-cache window.

For detailed changes, see [`CHANGELOG`](https://github.com/better-auth/better-auth/blob/1a3c8c478a94a7a2ddd1f0b62250b51f4fa0583f/packages/api-key/CHANGELOG.md)

## `@better-auth/electron`

### Bug Fixes

- Fixed Electron auth transfers to require S256 PKCE at both minting and exchange, rejecting plain and missing `code_challenge_method` values.

For detailed changes, see [`CHANGELOG`](https://github.com/better-auth/better-auth/blob/1a3c8c478a94a7a2ddd1f0b62250b51f4fa0583f/packages/electron/CHANGELOG.md)

## `@better-auth/scim`

### Bug Fixes

- Fixed SCIM user provisioning to return 409 when a user with the same email already exists unless `linkExistingUsers` is set, changed org-scoped `DELETE` to deprovision the user rather than delete the global account, and added `canGenerateToken` to control SCIM token creation.

For detailed changes, see [`CHANGELOG`](https://github.com/better-auth/better-auth/blob/1a3c8c478a94a7a2ddd1f0b62250b51f4fa0583f/packages/scim/CHANGELOG.md)

## Contributors

Thanks to everyone who contributed to this release:

@Bekacru, @gustavovalverde

**Full changelog:** [`v1.6.15...v1.6.16`](https://github.com/better-auth/better-auth/compare/v1.6.15...v1.6.16)