I Run a Next.js Site on Vercel Behind Cloudflare. Of the 13 May Advisories, Exactly One Threatens a Cache-Fronted RSC Stack, and It Isn't the SSRF Everyone Screenshotted.
Next.js shipped 13 coordinated security advisories on May 6 2026 and patched releases on May 7. This is the operator triage from a real Vercel-hosted App Router site fronted by a Cloudflare edge cache: which of the 13 can physically reach a stack like yours, why the headline self-hosted SSRF probably can't, why the RSC cache-poisoning advisory is the one that matters when you cache responses at the edge, the exact upgrade including the Turbopack follow-up trap, and what broke on 16.2.6.

The Threads screenshot is CVE-2026-44578, the WebSocket SSRF that reaches your cloud metadata endpoint. On my stack it's unreachable, and it's the wrong thing to panic about. The one that can poison every page my readers see is a Moderate nobody is screenshotting.
The one-line situation, and the triage that actually matters
Next.js shipped 13 coordinated security advisories on May 6, 2026, and patched releases on May 7: versions 16.2.6 and 15.5.18. The press lined up behind CVE-2026-44578, the WebSocket SSRF, because the screenshot is good: an attacker upgrades a connection, the server walks itself to 169.254.169.254, and the metadata endpoint hands back IAM credentials. Dramatic.
It's also self-hosted only. On a Vercel-managed deployment fronted by Cloudflare, that path is unreachable. The advisory that can reach my readers is the Moderate RSC cache-poisoning one nobody is posting, because a poisoned RSC response doesn't stay on the attacker's request – it lands in my shared edge cache and gets served to every visitor until I purge the tag.
If you run any Next.js >= 13.4.13, you are upgrading this week. The only questions are to what version, in what order, and what you have to retest afterward. The triage below is the matrix I ran on omidsaffari.com – App Router on Vercel, Cloudflare in front with Cache-Tag purge and a revalidate webhook – and the conclusion that flipped my prioritization away from the headline CVE.
What this means for non-technical founders
If your product is a Next.js app, this is a this-week line item, not a backlog ticket. The dollar framing isn't latency or developer hours – it's that a poisoned cached page or an auth-bypassed admin route is a customer-trust event. One screenshot of your marketing page rendering attacker content, one report of someone reaching /admin without a session, and you spend the next week explaining instead of selling.
Ask your engineers exactly one question: "Are we on 16.2.6 or 15.5.18, and did we purge the edge cache after deploying?" If the answer is vaguer than that – "we're patching", "it's in progress", "the SSRF doesn't affect us" – it isn't done. Self-hosted deployments (ECS, EC2, Kubernetes, anything running next start on a server you operate) are the higher-risk bucket because they're exposed to the SSRF as well as everything else. Ask which one you are. The answer should take ten seconds.
The 13, sorted by whether they can reach your stack
The mistake in every "13 CVEs patch now" post going around is treating the list as flat. It isn't. Each advisory has a precondition – self-hosted, Turbopack, Cache Components, CSP nonces, i18n – and your real exposure is the subset where your deployment matches. Here's the same 13 grouped by the conditions they need to fire.
Middleware and proxy bypass cluster (5 advisories, mostly High). The biggest one is GHSA-267c-6grr-h53f, which lets an App Router segment-prefetch URL route past middleware auth checks. The cluster also includes its incomplete-fix follow-up published May 7 (GHSA-26hh-7cqf-hhc6) for Turbopack, a Pages Router i18n default-locale path bypass, and a dynamic-route parameter injection bypass. Precondition: you use Next.js middleware to enforce auth or rewrites. Almost everyone does.
SSRF, CVE-2026-44578. WebSocket upgrade handler in the self-hosted server reaches internal HTTP endpoints on port 80, including cloud metadata. Affected: 13.4.13+ through <15.5.16 and 16.0.0–<16.2.5, self-hosted only. Vercel-managed deployments are confirmed not affected.
Denial of service, two advisories. One is the upstream RSC DoS; the second is a connection-exhaustion DoS in apps opted into Cache Components (High, GHSA-q4gf-8mx6-v5v3). Precondition for the second one: you've explicitly enabled Cache Components – most apps haven't.
RSC cache poisoning (Moderate). Cache-busting collisions in the RSC payload pipeline let a crafted request poison a cached response. Precondition: you cache RSC responses anywhere downstream – CDN, reverse proxy, Vercel's edge, Cloudflare. This is the one that matters on my stack.
XSS, two advisories. CVE-2026-44581 (Moderate) in App Router apps generating CSP nonces, and an XSS in beforeInteractive scripts consuming untrusted input. Preconditions: you ship a CSP with nonces, or you pass user input into a beforeInteractive script tag.
Write down which preconditions your deployment meets. That's your real list. For omidsaffari.com, it's: middleware bypass cluster (yes), SSRF (no, Vercel-hosted), RSC DoS (yes, upstream), Cache Components DoS (no, not opted in), RSC cache poisoning (yes, and amplified), CSP nonce XSS (yes), beforeInteractive XSS (no). Eight High/Moderate advisories collapse to five that apply to me, and the one with the worst blast radius isn't the famous one.
Why the SSRF everyone is screenshotting probably isn't your problem, and the cache-poisoning one is
CVE-2026-44578 needs the Node-side next start server to handle the WebSocket upgrade and walk the redirect. Vercel doesn't run my requests through that server in a way that makes the SSRF path reachable – the platform terminates WebSockets, and the metadata endpoint sits behind IMDSv2 with a hop limit that wouldn't survive the path anyway. Cloudflare in front of that doesn't change the conclusion. On a Vercel + Cloudflare topology, the dramatic screenshot doesn't render.
The RSC cache-poisoning advisory inverts that completely. The vulnerability is in the request-handling path that everyone hits, and the consequence is a poisoned RSC payload, meaning the serialized React tree your readers receive. On my site that payload doesn't stay on the attacker's request. It lands here:
Cache-Control: public, s-maxage=300, stale-while-revalidate=86400
Cache-Tag: article:nextjs-may-2026-security-triages-maxage=300 means Cloudflare holds that response for five minutes. stale-while-revalidate=86400 means it will keep serving it for a day past expiry while it revalidates in the background. The Cache-Tag is how I purge – when I publish a new revision, the revalidate webhook fires a tag purge and the object drops out.
Walk through what happens with a poisoned response. The attacker hits a route that the cache-busting collision exploits. Cloudflare sees a cacheable response, stores it under that URL's cache key, tags it article:<slug>. Every subsequent visitor to that slug gets the poisoned RSC payload from the edge – not from origin, not through any middleware, not through any WAF rule I add ten minutes later. The poisoned object is already downstream. It sits there until the s-maxage window expires or my publish pipeline fires a purge. WAF rules at the origin do nothing for a response that's already in 300 PoPs.
This is why the asset at risk is the published content surface – the content engine output – not an internal API. The 13-advisory list ranks the SSRF as High and this one as Moderate. On a cache-fronted RSC site, the practical impact ordering is reversed.
The upgrade, exactly, including the Turbopack follow-up trap
Step one: find out what you're on. package.json lies about the resolved version when you have a caret range; check the lockfile.
bun pm ls | grep next
# or
npm ls nextThen pin to 16.2.6 (Next.js 16 line) or 15.5.18 (Next.js 15 line). Not 16.2.5. Not 15.5.16.
bun add next@16.2.6
# or
npm install next@16.2.6 --save-exactThe reason for the exact pin is the trap nobody is mentioning. The original 13 advisories were patched in 16.2.5 / 15.5.16 on May 6. On May 7, Vercel shipped GHSA-26hh-7cqf-hhc6 – an incomplete-fix follow-up for the segment-prefetch middleware bypass that remained exploitable when the request was served through Turbopack. Non-Turbopack users were protected at 16.2.5 / 15.5.16. Turbopack users were not. The full fix is 16.2.6 / 15.5.18.
If you're on the 13.x or 14.x line, there is no patch coming. Vercel isn't backporting. The remediation is a 15.x or 16.x migration, and you should scope it as a migration – not a bun update. Budget a week minimum if you have a non-trivial app; the breaking surface is real, especially around middleware matchers and the App Router's caching defaults.
After the deploy lands, purge the edge cache. This is the step missing from every other write-up I've read this week. If you don't purge, any RSC payload Cloudflare cached before the patch went live is still there, possibly poisoned if anyone hit the exploit during the window, and still served from the edge until s-maxage expires. On my stack:
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/purge_cache" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"purge_everything": true}'Then verify. Pick a route protected by middleware auth, craft the segment-prefetch URL shape from the advisory write-up, and replay it against production. You should get a 401 / 302 / whatever your middleware returns for unauthenticated requests. If you get a 200 with content, the middleware patch didn't take and you have a deployment problem, not a Next.js problem.
What broke on 16.2.6 (the honest part)
The honest part is that these aren't pure security patches. Several of them deliberately change routing and cache-key behavior, because the vulnerabilities were in routing and cache-key behavior. So expect deltas.
Middleware matcher tightening on .rsc and segment-prefetch URLs. The segment-prefetch bypass fix changed how matchers match. If you had a matcher pattern that relied on the old shape – particularly if you were using a negative lookahead to exclude _next paths and assumed .rsc was always under that – re-verify. I had to widen one matcher to explicitly catch the segment-prefetch suffix on a protected route. Five-minute fix, but it would have been a silent regression if I hadn't replay-tested.
CSP nonce handling. The XSS fix (CVE-2026-44581) changes how nonces propagate through the App Router render. If you generate nonces in middleware and reference them in a Script component, run your CSP in report-only mode for a day after deploy. I didn't see any violations, but the change is real and I've heard from one team that had to update their nonce-generation flow.
Cache Components behavioral change. If you're on Cache Components for the connection-exhaustion DoS fix path, the fix changes how cache misses are coalesced under load. Retest your hot paths. I'm not on Cache Components so I didn't have to.
The verification checklist I ran before calling the upgrade done:
[ ] next version pinned to 16.2.6 in lockfile
[ ] middleware auth replay on /admin via segment-prefetch URL → 401
[ ] middleware auth replay via .rsc URL → 401
[ ] RSC cache key sanity: same URL, two clients, identical payload
[ ] forced edge purge after deploy
[ ] CSP report-only on for 24h with no new violations
[ ] one full revalidate cycle on a high-traffic pageBudget a staging pass. This is not a zero-risk patch bump because the security fixes deliberately change routing and cache-key behavior. The difference between a Tuesday-afternoon deploy and a Tuesday-night incident is whether you replay-tested the auth paths before you flipped production.
Patch, don't WAF, and the structural lesson
Vercel shipped no WAF rules for this release. The changelog states patching is the only complete mitigation, and they're right – none of these advisories are filterable cleanly at the edge because the malicious request shapes overlap too heavily with legitimate ones. Cloudflare shipped WAF rules and framework-adapter mitigations on May 6 as defense in depth, not as a replacement for upgrading. Read the wording carefully: the Cloudflare changelog is explicit that the WAF rules reduce exposure during the rollout window, not after.
That distinction is the structural lesson from this week. A stack that can upgrade a framework, redeploy, and purge its edge cache in a single afternoon turns a 13-CVE coordinated disclosure into a Tuesday line item. A stack that can't – because the upgrade requires a migration, because there's no purge primitive, because the deploy pipeline has manual gates – is exposed for as long as the rollout takes. Days. Sometimes weeks.
This is the same pattern as the agent blast-radius argument: structural fast-recovery beats reactive filtering. You don't prevent every bad request, you don't prevent every bad agent call. You build the system so that when one lands, the response window is measured in minutes and the blast radius is contained by topology, not by hope.
Upgrade tonight. Pin 16.2.6 or 15.5.18. Purge the cache after. The screenshot CVE is the wrong thing to worry about; the Moderate that touches every cached page is the one that matters.
Do I need to upgrade if I'm hosted on Vercel?
Yes. Vercel only neutralizes the self-hosted SSRF (CVE-2026-44578); the middleware-bypass, RSC cache-poisoning, DoS, and XSS advisories still apply to Vercel-hosted App Router apps.
Is 16.2.5 / 15.5.16 enough, or do I need 16.2.6 / 15.5.18?
Go to 16.2.6 / 15.5.18. The earlier builds fixed the original 13, but a May 7 follow-up (GHSA-26hh-7cqf-hhc6) re-opened the segment-prefetch bypass for Turbopack users.
I'm on Next.js 14, where's the patch?
There isn't one. 13.x and 14.x get no patches; the only remediation is migrating to 15.x or 16.x – scope it as a migration, not a version bump.
Can a Cloudflare or Vercel WAF rule hold me until I upgrade?
Only as defense in depth. Cloudflare shipped WAF and adapter mitigations on May 6; Vercel shipped none and states patching is the only complete fix.
Which advisory actually threatens a cache-fronted RSC site?
The RSC cache-poisoning advisory. A poisoned response cached behind s-maxage at the edge is served to every visitor until the Cache-Tag is purged.
May 17, 2026
More from Dev

Three AI Agents Deleted Three Production Databases in 90 Days. Here's the Cloudflare Blast-Radius Architecture I Run So My Six Agents Structurally Can't.
In 90 days Cursor wiped PocketOS in nine seconds, Claude Code ran terraform destroy on DataTalks.Club's 1.9-million-row database, and Amazon's Kiro deleted an AWS production environment for a 13-hour outage. This is the production blast-radius architecture I run across six Cloudflare agents: a single callAi() cost chokepoint with hard caps, a 12-tool Zod allowlist with no shell and no infra API, idempotent Workflow steps, and the Claude Agent SDK dontAsk config that makes pre-execution denial the only safeguard that works when you have nine seconds to react.
May 16, 2026
Anthropic Just Shipped Outcomes, Multiagents, and Webhooks for Managed Agents in SDK 0.100. Here's the Cloudflare Workflow Code I'm Deleting — and the One File I'm Keeping.
A migration playbook for senior devs running production AI on a Durable-Object-plus-Workflows stack. Maps every piece of the Managed Agents API that landed in SDK 0.100–0.102 to the Cloudflare primitive it replaces, surfaces the three…
May 15, 2026
Bun 1.3.14 Drops Bun.Image as a Sharp Drop-In. Here's the 4-Step Migration I Ran on My Image Pipeline.
A working migration playbook for senior devs running production image workloads on Bun. Maps every Sharp method I had in production to its Bun.Image equivalent, surfaces the four API differences that broke first, and benchmarks the result…
May 14, 2026