Niska

Better Auth: Stale sessions persist after user deletion across admin, anonymous, and SCIM flows

  • Ujawniono: 07.07.2026
  • Aktualizacja: 11.10.2026 10:22

Am I affected?

Users are affected if all of the following are true:

  • They configure secondaryStorage on betterAuth(...) (Redis, KV, or any external session cache).
  • session.storeSessionInDatabase is left unset or set to false (the default).
  • Their application's deployment uses one or more of:
    • The admin plugin and calls auth.api.removeUser(...) or authClient.admin.removeUser(...).
    • The anonymous plugin and exposes /delete-anonymous-user or relies on the after-link hook to clean up the anonymous user.
    • The @better-auth/scim plugin and exposes DELETE /scim/v2/Users/:userId.

If storeSessionInDatabase is true, sessions are also written to the database, and the database delete cascades; users are not affected.

Fix:

  1. Upgrade to better-auth@<patched-version> or later (and @better-auth/scim@<patched-version> if they use SCIM).
  2. If they cannot upgrade, see workarounds below.

Summary

When secondaryStorage is configured and storeSessionInDatabase is false, three user-deletion endpoints in better-auth plus one in @better-auth/scim call internalAdapter.deleteUser(userId) without first calling internalAdapter.deleteSessions(userId). The deleted user's session payload (which carries a cached user object) remains in secondary storage, and internalAdapter.findSession(token) keeps returning it as a valid session until the session TTL elapses (default 7 days).

Details

The vulnerable call sites are:

  • admin plugin's removeUser (packages/better-auth/src/plugins/admin/routes.ts:1463).
  • anonymous plugin's self-delete endpoint (packages/better-auth/src/plugins/anonymous/index.ts:222).
  • anonymous plugin's after-link hook (packages/better-auth/src/plugins/anonymous/index.ts:325).
  • @better-auth/scim's DELETE /scim/v2/Users/:userId (packages/scim/src/routes.ts:1019).

Working callers that already do the right thing: the core /delete-user self-delete and /delete-user/callback (packages/better-auth/src/api/routes/update-user.ts:551).

The fix shape extends each vulnerable caller to invoke deleteSessions(userId) before deleteUser(userId). The architectural follow-up centralizes the cleanup inside deleteUser itself or introduces a single deleteUserAndSessions orchestrator so future callers cannot regress this contract.

Patches

Fixed in better-auth@<patched-version> and @better-auth/scim@<patched-version>. All four user-deletion call sites now invoke deleteSessions(userId) before deleteUser(userId) so sessions are evicted from secondary storage at the same time the user row is removed.

Workarounds

If users cannot upgrade immediately:

  • Configuration-level: set session.storeSessionInDatabase: true. Subsequent user-delete writes reach the session table and the database cascade removes rows. Increases write volume for high-throughput sessions but eliminates the gap.
  • Code-level (admin path): when calling auth.api.removeUser, also call auth.api.revokeUserSessions({ body: { userId } }), which uses deleteSessions internally.
  • Code-level (SCIM path): wrap their SCIM provider's deprovisioning hook to call auth.api.revokeUserSessions(...) after the SCIM DELETE.
  • Code-level (anonymous path): in onLinkAccount, explicitly call internalAdapter.deleteSessions(anonymousUser.user.id) before allowing the new session to be issued.

Impact

  • Stale session validity: a deleted user's existing session cookie continues to authenticate against getSessionFromCtx until the session TTL elapses (default 7 days). Within that window, the deleted user retains their pre-existing read and write surface.
  • SCIM-driven deprovisioning gap: organizations using SCIM to revoke offboarded employees' access do not, in fact, revoke active sessions. The deleted account remains usable for up to 7 days after deprovisioning.

Credit

Reported by @iruizsalinas.

Resources

Czego dotyczy

Kliknij technologię, aby zobaczyć wszystkie dotyczące jej podatności.

PlatformaPaczkaPodatne wersjePoprawka w wersji
Paczka npm better-auth >= 0.3.4, < 1.6.11 1.6.11
Paczka npm @better-auth/scim >= 1.6.0, < 1.6.11 1.6.11

Odnośniki

Ocena CVSS 3.8/10
Wektor CVSS
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:N
Słabość (CWE)
CWE-459, CWE-613, CWE-672
Platforma
npm
Paczka
better-auth, @better-auth/scim
Ujawniono
07.07.2026
Aktualizacja
11.10.2026 10:22

Źródła i licencje

OSV / GitHub Advisory Database - GHSA-2vg6-77g8-24mp - CC BY 4.0

Historia podatności: better-auth

Wszystkie opisane podatności tej paczki (Paczka npm), od najnowszej. Widać, czy to jednorazowa wpadka, czy paczka, której trzeba pilnować.

Wszystkie (22) w archiwum
Wszystkich wpisów
22
Pierwsza → ostatnia
12.2024 07.2026
Bez poprawki
0
Wykorzystywana w atakach
0

Rozkład istotności

  • Krytyczna 2
  • Wysoka 14
  • Średnia 3
  • Niska 3

Ujawnienia w latach

  1. 2024: 1
  2. 2025: 8
  3. 2026: 13
Istotność:
  1. Wysoka · 8.3 CVE-2026-67327 >= 1.1.3, < 1.6.22, >= 1.7.0-beta.0, < 1.7.0-beta.10 1.6.22, 1.7.0-beta.10
  2. Better Auth: Stale sessions persist after user deletion across admin, anonymous, and SCIM flows ten wpis
    Niska · 3.8 CVE-2026-67334 >= 0.3.4, < 1.6.11 1.6.11
  3. Wysoka · 8.1 CVE-2026-53517 >= 1.4.8-beta.7, < 1.6.0 1.6.0
  4. Wysoka · 7.7 CVE-2026-67333 < 1.6.13, >= 1.7.0-beta.0, < 1.7.0-beta.4 1.6.13, 1.7.0-beta.4
  5. Wysoka · 7.3 CVE-2026-45364 < 1.4.17, >= 1.5.0-beta.1, < 1.5.0-beta.9 1.4.17, 1.5.0-beta.9
  6. Wysoka · 8.6 CVE-2025-61928 < 1.3.26 1.3.26

Dowiedz się, które podatności dotyczą Twojej aplikacji

Po podłączeniu integracji DockRay i włączeniu raportowania oprogramowania DockRay porównuje zgłoszone wersje komponentów ze znanymi podatnościami i powiadamia o potwierdzonych dopasowaniach. Zakres zależy od obsługiwanej technologii i dostępnych biuletynów.

Podłącz swoją aplikację
Newsletter DockRay

Bezpieczeństwo aplikacji w Twojej skrzynce

Najważniejsze podatności, konkretne zalecenia i praktyczne wskazówki dla Twoich aplikacji. Wybierz technologie i śledź to, co ma znaczenie dla Twojego projektu.

  • Codzienne zestawienie nowych podatności, także krytycznych.
  • Powiadomienia o ważnych aktualizacjach.
  • Praktyczne porady o bezpieczeństwie i monitoringu aplikacji.

Pozostaw puste, aby otrzymywać informacje o wszystkich technologiach.

Zapis jest bezpłatny. Wypiszesz się jednym kliknięciem w wiadomości.