Clerk's createRouteMatcher bypass (CVE-2026-41248): check that you are patched
In April 2026 Clerk disclosed a critical flaw that let crafted requests skip middleware route protection in its Next.js, Nuxt and Astro SDKs. Six months on, here is what it was, which versions fix it, and why a middleware check should never be your only auth check.
Most of what we write about Clerk concerns availability: whether users can sign in. This article is about the opposite failure, where someone gets in who should not.
On 15 April 2026, Clerk published a security advisory for a flaw in createRouteMatcher, the helper most Clerk apps use to decide which routes need a signed-in user. It was rated critical, with a CVSS score of 9.1. The fix has been available since that day. Apps that have not updated their Clerk packages since early April are still exposed, so it is worth five minutes to check.
What the flaw was
A typical Clerk middleware file looks like this:
const isProtectedRoute = createRouteMatcher(['/admin(.*)']);
export default clerkMiddleware(async (auth, req) => {
if (isProtectedRoute(req)) {
await auth.protect();
}
});
The matcher looks at each request and says whether it is for a protected route. According to the advisory, a specially crafted request could make the matcher give the wrong answer. The middleware then let the request through without a sign-in check, and it reached the API route or server component behind it.
The advisory scores it as exploitable over the network, with low complexity, no privileges and no user interaction.
Clerk is clear about the limit of the damage: "Sessions are not compromised and no existing user can be impersonated—the bypass only affects the middleware-level gating decision." An attacker could not become another user. They could reach a page or endpoint as nobody, which is serious if that endpoint assumed the middleware had already checked.
Affected and fixed versions
| Package | Affected | Fixed in |
|---|---|---|
@clerk/nextjs |
5.0.0 – 6.39.1, 7.0.0 – 7.2.0 | 5.7.6, 6.39.2, 7.2.1 |
@clerk/nuxt |
1.1.0 – 1.13.27, 2.0.0 – 2.2.1 | 1.13.28, 2.2.2 |
@clerk/astro |
0.0.1 – 2.17.9, 3.0.0 – 3.0.14 | 1.5.7, 2.17.10, 3.0.15 |
@clerk/shared |
2.20.17 – 3.47.3, 4.0.0 – 4.8.0 | 2.22.1, 3.47.4, 4.8.1 |
The table follows the GitHub advisory, which is the authoritative list. To see what you have installed, run npm ls @clerk/nextjs @clerk/shared (or the Nuxt or Astro package). Check @clerk/shared as well, because it is installed as a dependency and a lockfile can hold it on an old version.
Who was not affected
The advisory lists three cases:
- apps that use the inverted pattern, where the matcher lists public routes and everything else is protected;
- apps that also check auth inside route handlers or server components;
- external APIs that authenticate each request with its own token.
The timeline
The advisory credits Christiaan Swiers (@YouGina) with responsible disclosure. It was reported on 13 April 2026, and Clerk patched and disclosed it on 15 April. Two days from report to fix is fast.
It came during a hard stretch for Clerk. The company had published three outage postmortems in February and March and had just moved most of its engineers onto reliability work.
The lesson: middleware is not enough
This was not the first time middleware-only protection failed in this ecosystem. In March 2025, Next.js itself had a critical middleware authorization bypass (CVE-2025-29927). The framework was different and the bug was different, but the outcome was the same: requests reached code that trusted the middleware to have stopped them.
Clerk's advisory gives the fix for the whole class of problem: "Adding server-side auth checks (auth()) inside your route handlers, server components, or server actions provides defense-in-depth against this bypass."
In practice:
- Check auth where the data is read or changed. Call
auth()in the route handler, server action or server component, and reject the request there if there is no user. - Treat middleware as a convenience. It is good for redirecting signed-out visitors to the sign-in page. It should not be the only thing between the internet and your database.
- Prefer listing public routes. If you forget to list a route, it ends up protected instead of open. The advisory also says this pattern was not affected.
- Keep auth packages current. Let Dependabot or Renovate open pull requests for
@clerk/*packages, and merge security releases quickly.
What to do now
- Run
npm lsfor your Clerk packages and compare against the table. - Upgrade if you are in an affected range. Clerk's instruction was to "upgrade immediately."
- Review endpoints that rely only on middleware, especially admin routes and anything that returns customer data. If you ran an affected version in production, check your logs for unexpected requests to those routes.
- Subscribe to security advisories on the clerk/javascript repository.
A status page will not warn you about a vulnerability, because nothing is down. Uptime monitoring and security patching are separate jobs, and an app that depends on a third-party auth provider needs both. For the uptime half, isuptime tracks Clerk's live status along with 102 other services.
Sources
- Middleware-based route protection bypass (GHSA-vqx2-fgx2-5wq9, CVE-2026-41248) (Clerk, GitHub Security Advisory)
- Middleware-based route protection bypass (Clerk)
- Postmortem on Next.js Middleware bypass (CVE-2025-29927) (Vercel)
- Postmortem: Clerk System Outage (March 10, 2026) (Clerk)
Live status for the services in this post
Checked continuously against each provider's own status feed.