
Cloud Vulnerability DB
A community-led vulnerabilities database
authenticateRequest() and verifyToken() in @clerk/backend could accept an OIDC ID token as a session token. Clerk issues ID tokens to OAuth clients that are granted the openid scope, and signs them with the same instance key as session tokens. A third-party OAuth client that a user approved could send that user's ID token to any other application on the same Clerk instance and be authenticated as that user, with access beyond the scopes the user granted.
An ID token carries the user's identity (sub, sid, and org_id when the organization scope was granted) but no organization role, organization permissions, or factor verification age. Checks that need any of those still fail closed for a replayed ID token: has() and auth.protect() with role, permission, or reverification return false. The attacker is limited to what the application allows a signed-in user with no organization role, and only for users who approved the attacker's OAuth client.
Applications that verify Clerk session tokens with @clerk/backend, directly or through a framework SDK (@clerk/nextjs, @clerk/express, @clerk/remix, @clerk/react-router, @clerk/tanstack-react-start, @clerk/astro, @clerk/nuxt, @clerk/fastify, @clerk/hono, and others), whose Clerk instance issues ID tokens. That is any instance with an OAuth application allowed the openid scope, with dynamic client registration enabled, or with Client ID Metadata Document (CIMD) clients enabled.
Instances with none of these do not issue ID tokens and are not affected.
On 07 NOV 2026 Clerk started tagging every ID token with its own token category. ID tokens have a fixed 24 hour lifetime, so every ID token issued before the change has expired. What the change covers depends on your version:
@clerk/backend 3.17.0 and later: authenticateRequest() rejects these ID tokens with no upgrade needed.@clerk/backend 3.16.9 to 3.16.11: authenticateRequest() rejects them on the default session path, but not when acceptsToken is 'any' or an array.verifyToken() directly is not covered on any released version.
All of these need the patched release.Upgrade @clerk/backend to the patched release on your current major:
@clerk/backend 3.x): 3.28.0 or later@clerk/backend 1.x and 2.x): 2.33.9 or later
Current framework SDK releases depend on @clerk/backend through a caret range, so updating the lockfile entry is enough, for example npm update @clerk/backend. Check the installed version with npm why @clerk/backend.
Older Core 2 framework releases pin an exact 1.x @clerk/backend, and npm update @clerk/backend does nothing for them: @clerk/nextjs before 5.7.7, @clerk/remix before 4.4.0, @clerk/astro before 1.6.0, and @clerk/fastify before 2.1.0. Upgrade the framework package to its latest Core 2 release.
Core 1 (@clerk/backend 0.x) is also affected. It is no longer supported and will not receive a patch. Upgrade to Core 2 or Core 3.If you cannot upgrade immediately:
@clerk/backend 3.11.1 or later, set authorizedParties in authenticateRequest() / clerkMiddleware(). ID tokens carry no azp claim, and these versions reject a token without azp once authorizedParties is set. This does not work on 2.x, 1.x, or 3.0.0 to 3.11.0, which skip the check when azp is missing.decodeJwt throws on a malformed token, so treat a throw as a rejection too:import { decodeJwt } from '@clerk/backend/jwt';
const { header } = decodeJwt(token);
// cl_B7d4PD444AAA is the token category Clerk stamps on OIDC ID tokens.
if ((header as { cat?: string }).cat === 'cl_B7d4PD444AAA') {
// not a session token
}This issue was reported on 07 NOV 2026, mitigated server-side on 07 NOV 2026, patched in @clerk/backend on <DATE>, and publicly disclosed on <DATE>.
Thanks to Lucas Valbuena for the responsible disclosure of this vulnerability.
Source: NVD
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."