Executive brief
Effect's RPC and web handler implementation loses or mixes up AsyncLocalStorage (ALS) context between concurrent requests under load. This allows authentication functions (like Clerk's auth()) called within Effect fibers to read the wrong user's session data. In production with concurrent traffic, a user could gain unauthorized access to another customer's account or data by timing their requests to coincide with others' operations.
Technical details
Effect's MixedScheduler drains batched fiber continuations inside a single microtask or timer callback, inheriting the AsyncLocalStorage context of whichever request first triggered the drain cycle. The toWebHandlerRuntime function correctly sets Effect's own Context per-request but does not capture or restore Node.js AsyncLocalStorage context when forking fibers. Under concurrent load, when Request A triggers a scheduler drain, all subsequent continuations—including those from Request B—execute within Request A's ALS context. This affects any ALS-dependent APIs: calling auth() from @clerk/nextjs/server returns the wrong user's session, Next.js cookies() / headers() read the wrong request, and OpenTelemetry trace context crosses request boundaries. The vulnerability requires concurrent requests to the same handler and is highly likely to occur under production traffic. A fix was applied in Effect 3.20.0 or later to properly capture and restore ALS context at fiber fork/resume time.
Affected products
- Effect-TS effect <= 3.19.15
- Effect-TS @effect/rpc <= 0.72.1
- Effect-TS @effect/platform <= 0.94.2
Timeline
- 2026-03-20: disclosed: Security advisory GHSA-38f7-945m-qr2g published
- 2026-03-20: patched: Patch available in effect >= 3.20.0