
Stopping React's Perfect-10 RCE Before It Stops You

CVE-2025-55182, Next.js, and why your WAF configuration matters today—not “after the sprint”
TL;DR
A new React Server Components / React Server Functions vulnerability, CVE-2025-55182, was disclosed with a CVSS score of 10.0—the highest possible. It enables unauthorized Remote Code Execution (RCE) on vulnerable React 19 / Next.js App Router environments, particularly those exposing the React Server Flight protocol.
By now, your feed is probably full of excellent, 3,000-word breakdowns of how the bug works internally. This post doesn’t try to be yet another “here’s the protocol, step by step” explainer—instead, it focuses on what most teams are still missing: real labs, concrete mitigations, and multi-platform coverage that actually reduces risk.
In theory (and in practice), this bug is very weaponizable:
- RCE over HTTP on internet-facing Next.js apps
- Simple primitives to exploit once you understand the protocol
- Easy to scan at scale and integrate into automated exploit frameworks
So rather than rehashing the full exploit chain, we concentrate on:
- How to quickly check whether your stack is affected (and patch)
- How to get your WAFs on Cloudflare, AWS, Akamai, Azure, and More into meaningful
Blockmode for this issue and how we provide rules for platforms that lack them, such as Azure. - How we built labs, scanners, and cross-platform mitigations so you’re protected even where vendors were slow to ship native coverage
At Huskeys, we moved quickly on a different axis: closing the gaps where vendor coverage was missing or delayed. We built a cross-platform mitigation that:
- Works consistently across providers like Cloudflare, AWS, Akamai, and Azure (and others in your stack)
- We've included an example of a concrete Azure WAF policy for environments that didn’t yet have a named CVE rule
- Is backed by a lab that reproduces the vulnerable RSC behavior and a scanner that finds potentially exposed assets
Only after that did we layer in vendor-specific protections. Cloud providers also moved fast:
- Cloudflare pushed an emergency WAF managed rule update to cover the vulnerability, now labeled “React – RCE – CVE-2025-55182” in both the Cloudflare Managed Ruleset and Free Ruleset [Cloudflare changelog].
- AWS published a security bulletin with patch guidance and shipped updated managed WAF protections (and a suggested custom rule) [AWS security bulletin].
- Akamai released research on the React / Next.js Server Functions deserialization RCE and practical exploit paths, including guidance on detection and mitigation on their edge platform [Akamai research].
We highly recommend turning these emergency rules to Block mode on all relevant zones and environments. And because not every stack lives on a single provider, our goal was to make sure that missing platforms were covered too - in this blog we will focus on Azure as an example of one of them.
What is CVE-2025-55182 and who is affected?
The short version: if you’re running React 19 with Server Components / Server Functions or Next.js App Router, you need to care.
According to the public advisories, the bug affects:
- React 19.0, 19.1, 19.2 when using Server Components / Server Functions over the React Server Flight protocol
- Next.js 15.x, 16.x, and late 14.3.0 canary builds using App Router and the RSC transport
Under the hood, the issue sits in how React Server Components payloads are deserialized and resolved on the server. Crafted payloads can smuggle malicious “resolved models” into the execution path, eventually leading to arbitrary code execution on the application server.
Why the 10.0 score?
- Remote: Exploitable purely via HTTP(S)
- Unauthenticated: In many deployments, the affected endpoints are public
- Code Execution: Successful exploitation means full RCE on your app server
- Impact radius: Compromised Next.js app → potential access to internal APIs, secrets, and data stores behind it
Even teams with good patch discipline can’t always upgrade React or Next.js the same day a bug drops. That’s where WAF-level mitigations buy you time.
Why this bug is so “scan-friendly”
Most breaking web vulns fall somewhere between “requires deep context” and “needs a custom chain per app.” This one leans toward the opposite:
- Protocols are standardized: The React Server Flight / RSC protocol is fairly consistent between apps.
- Headers and fields are predictable: Attackers can key off:
- HTTP
POSTmethods - RSC-related headers like
next-actionorrsc-action-id - JSON bodies with suspicious
status: "resolved_model"segments or special markers like$@
- HTTP
- Error behavior is observable: It’s not hard to distinguish “blocked,” “no RSC present,” and “crashing server” patterns.
That combination makes it ideal for mass scanning:
- Enumerate Next.js / React app endpoints
- Send RSC-shaped probes in bulk
- Classify responses and iterate payloads
You don’t want to be discovered in step 2.
How to check if you’re affected (and patch quickly)
WAF mitigations buy you time, but they don’t replace patching. At the application level, there are two immediate questions to answer:
- Are we running a vulnerable React / Next.js version?
- Are we using any framework that bundles the vulnerable
react-serverimplementation under the hood?
To get there fast, our research team (led by Haviv Vaizman and Yotam Mazurik) recommends:
- Search all
package.jsonand lock files (package-lock.json,pnpm-lock.yaml,yarn.lock) for:reactreact-domreact-server-dom-webpack
- For those packages, look for vulnerable versions:
19.0.019.1.019.1.119.2.0
- Upgrade them to the patched versions:
19.0.119.1.219.2.1
For Next.js (App Router):
- Treat the following as vulnerable when using App Router:
14.3.0-canary15.x16.x
- Upgrade to one of the patched releases:
14.3.0-canary.8815.0.5,15.1.9,15.2.6,15.3.6,15.4.8,15.5.716.0.7
Finally, remember that any framework or library that bundles the React Server implementation is likely affected. This includes, but isn’t limited to:
- Next.js
- Vite RSC plugin
- Parcel RSC plugin
- React Router RSC preview
- RedwoodSDK
- Waku
If these appear anywhere in your dependency tree, treat them as potential exposure points and verify both framework version and how RSC is wired to the network.
How vendors (and Huskeys) responded
To make the landscape easier to digest, here’s how the major platforms reacted to CVE-2025-55182—and what we recommend you actually do:
ProviderWhat they shippedHuskeys recommendationReferenceCloudflareEmergency managed WAF rule labeled “React – RCE – CVE-2025-55182”, enabled in both the Cloudflare Managed Ruleset and Free Ruleset with Block as the action. Rule IDs 33aa8a8a948b48b28d40450c5fb92fba (Managed) and 2b5d06e34a814a889bee9a0699702280 (Free).Attach the ruleset to all zones hosting React 19 / Next.js apps and keep the rule in Block mode across prod, staging, and critical previews. Avoid disabling it globally due to noise; scope any needed exceptions narrowly.Cloudflare changelogAWSSecurity bulletin for CVE-2025-55182 (and the duplicate CVE-2025-66478), patched React/Next.js versions, updated AWSManagedRulesKnownBadInputsRuleSet (v1.24), plus a sample ReactJSRCE_CUSTOM WAF rule matching RSC-style requests and payload markers.Patch React/Next.js as soon as possible, enable the updated managed rules, and deploy the custom rule in Block mode in front of ALB/API Gateway and CloudFront where you terminate traffic for React/Next.js. Monitor false positives but don’t fall back to log-only as the default.AWS security bulletinAkamaiIn-depth research on the React / Next.js Server Functions deserialization RCE, including concrete exploit flows and recommended WAF defenses in Kona Site Defender—for example, inspecting POST requests to RSC/App Router endpoints, looking for RSC-specific headers (such as next-action / rsc-action-id) and serialized model markers (like \"status\":\"resolved_model\" and $@) in decoded bodies.Implement the Akamai WAF/KSD rules as outlined in their research to detect and block these RSC exploit patterns at the edge, and monitor for scanning and anomaly waves tied to those signatures.Akamai researchAzureNo named “CVE-2025-55182” managed rule at the time of writing; relies on custom WAF rules built on top of App Gateway / Front Door capabilities.Treat Azure as a first-class citizen in your mitigation plan: deploy targeted custom rules for RSC/App Router endpoints, including method/header/body inspection and decoding similar to AWS’ and Akamai’s guidance—ideally reusing a vetted template rather than ad-hoc signatures.HuskeysHuskeysBuilt a lab that reproduces the vulnerable React Server Components behavior, created a scanner to find potentially vulnerable assets across your inventory, and shipped a cross-platform mitigation strategy that normalizes protections across Cloudflare, AWS, Akamai, and Azure—including a concrete Azure rule set that closed the early gap.Use Huskeys as the control plane for this incident: map where you’re running vulnerable stacks, validate that each edge provider enforces an effective rule in Block mode, and keep the multi-cloud posture in sync over time instead of fixing one platform at a time.Huskeys and contact us for deeper guidance
The common pattern: vendors are doing the right thing quickly, but they’re doing it independently. Without a unifying layer, it’s easy to end up with Cloudflare fully protected, AWS half-configured, Akamai in detection-only mode, Azure forgotten in a backlog ticket, and other providers drifting in between.
Huskeys’ job is to make sure that never happens again.
How we built and validated our mitigations
We didn’t want to rely on theoretical signatures or vendor docs alone. To be confident in our guidance—across all the providers our customers use—we:
- Built a dedicated lab that reproduces the vulnerable React Server Components / Server Functions behavior:
- Realistic React 19 + Next.js App Router setups
- RSC/Flight traffic patterns and serialization flows
- Controlled exploit attempts to validate when RCE was actually achievable
- Created a scanner to find potentially vulnerable assets:
- Crawls and inventories domains, subdomains, and paths where React 19 / Next.js App Router is exposed
- Looks for RSC endpoints, framework fingerprints, and infrastructure hints across Cloudflare, AWS, Akamai, and Azure, etc
- Helps teams answer the most important question quickly: “Where are we actually exposed?”
- Designed a cross-platform mitigation strategy:
- Encoded the same detection ideas (methods, headers, payload markers, decoding steps) into:
- Cloudflare managed rule posture checks and tuning
- AWS managed/custom WAF rules
- Akamai edge/WAF policies informed by their research
- Azure WAF custom rules for App Gateway and Front Door
- Etc
- Validated in the lab that these rules block real exploit attempts without breaking legitimate RSC flows.
- Encoded the same detection ideas (methods, headers, payload markers, decoding steps) into:
Because many of the customers we work with run multi-cloud architectures, we treated being first to ship a practical Azure solution as non-negotiable, not an afterthought. Azure is a good example of the kind of platform that often doesn’t get a native, named mitigation for issues like this at all—if you’re only waiting for your cloud provider to save you, you’d still be exposed there today. That gap is exactly why Huskeys matters: you need a single brain coordinating protections across providers (Cloudflare, AWS, Akamai, Azure, and more), not a separate incident response for each one that drifts apart over time or leaves one cloud unprotected.
Huskeys’ stance: Turn it on, in Block mode
There are two easy mistakes to make with a CVSS 10.0 RCE:
- “We’ll wait for the next patch window.”
Attackers won’t. - “We enabled the rule—in Log mode.”
That’s not mitigation; that’s just telemetry.
Our position is simple:
- If you run vulnerable React / Next.js workloads behind a WAF, and your provider has shipped a dedicated rule for CVE-2025-55182, it should be in
Blockmode—today.
Across providers:
- Cloudflare: Ensure the React – RCE – CVE-2025-55182 managed rule is enabled and blocking.
- AWS: Use the updated AWSManagedRulesKnownBadInputsRuleSet (v1.24) and strongly consider the
ReactJSRCE_CUSTOMrule inBlock. - Akamai: Align your WAF and edge policies with the indicators and guidance in Akamai’s research, and enforce blocking on exploit-like RSC payloads at the edge.
- Azure: Deploy and harden a custom rule that mirrors the same detection logic, and promote it to
Blockonce validated.
Huskeys’ job is to make this shift safe and observable:
- Surface where your protection is missing, misconfigured, or drifting
- Correlate WAF behavior with application metrics so you don’t fly blind
- Coordinate multi-cloud rollouts so Cloudflare, AWS, Akamai, and Azure move together—not one at a time, weeks apart
Final thoughts
Perfect-10 vulnerabilities like CVE-2025-55182 are rare but predictable: modern frameworks grow more powerful, protocols get richer, and the attack surface grows with them.
You don’t get to choose when the next RCE drops—but you do get to choose how prepared you are when it does.
If you’re running React 19 or Next.js in production and want help validating your exposure and hardening your WAF posture across providers like Cloudflare, AWS, Akamai, Azure, and more, we’re already doing this work every day. We’re deliberately building Huskeys to be the first in the market that keeps you protected no matter which platform you’re on—with Azure support as a concrete proof of that promise. Reach out and we’ll walk through your stack together.
Appendix: Huskeys Azure WAF policy template for CVE-2025-55182
Below are example Azure WAF policies we use as a starting point to detect and block CVE-2025-55182-style traffic patterns—one for Application Gateway and one for Front Door. Both focus on:
POSTrequestsNext-Action/next-actionand related headersmultipart/form-datapayloads- Deserialization and prototype pollution markers in the body (such as
constructor:,__proto__:,prototype:,_response:) - Known scanner probe patterns (such as
$1:a:a,"status":"resolved_model", and$@)
You should adapt, test, and monitor this template for your own environment before rolling it out broadly:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"ApplicationGatewayWebApplicationFirewallPolicies_cve_waf_name": {
"defaultValue": "cve-waf",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies",
"apiVersion": "2024-07-01",
"name": "[parameters('ApplicationGatewayWebApplicationFirewallPolicies_cve_waf_name')]",
"location": "[resourceGroup().location]",
"properties": {
"customRules": [
{
"name": "CVE202555182RceProtochain",
"priority": 1,
"ruleType": "MatchRule",
"action": "Block",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RequestMethod"
}
],
"operator": "Equal",
"negationConditon": false,
"matchValues": [
"POST"
],
"transforms": [
"Uppercase"
]
},
{
"matchVariables": [
{
"variableName": "RequestHeaders",
"selector": "Next-Action"
}
],
"operator": "Any",
"negationConditon": false,
"matchValues": [],
"transforms": []
},
{
"matchVariables": [
{
"variableName": "RequestHeaders",
"selector": "Content-Type"
}
],
"operator": "Contains",
"negationConditon": false,
"matchValues": [
"multipart/form-data"
],
"transforms": [
"Lowercase"
]
},
{
"matchVariables": [
{
"variableName": "RequestBody"
}
],
"operator": "Contains",
"negationConditon": false,
"matchValues": [
"constructor:",
"__proto__:",
"prototype:",
"_response:"
],
"transforms": [
"Lowercase",
"UrlDecode"
]
}
],
"state": "Enabled"
},
{
"name": "CVE202555182ScannerProbe",
"priority": 2,
"ruleType": "MatchRule",
"action": "Block",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RequestMethod"
}
],
"operator": "Equal",
"negationConditon": false,
"matchValues": [
"POST"
],
"transforms": [
"Uppercase"
]
},
{
"matchVariables": [
{
"variableName": "RequestHeaders",
"selector": "Next-Action"
}
],
"operator": "Any",
"negationConditon": false,
"matchValues": [],
"transforms": []
},
{
"matchVariables": [
{
"variableName": "RequestHeaders",
"selector": "Content-Type"
}
],
"operator": "Contains",
"negationConditon": false,
"matchValues": [
"multipart/form-data"
],
"transforms": [
"Lowercase"
]
},
{
"matchVariables": [
{
"variableName": "RequestBody"
}
],
"operator": "Contains",
"negationConditon": false,
"matchValues": [
"$1:a:a"
],
"transforms": [
"Lowercase",
"UrlDecode"
]
}
],
"state": "Enabled"
},
{
"name": "NextWithProto2",
"priority": 8,
"ruleType": "MatchRule",
"action": "Log",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RequestMethod"
}
],
"operator": "Equal",
"negationConditon": false,
"matchValues": [
"POST"
],
"transforms": [
"Uppercase"
]
},
{
"matchVariables": [
{
"variableName": "RequestHeaders",
"selector": "Next-Action"
}
],
"operator": "Any",
"negationConditon": false,
"matchValues": [],
"transforms": []
},
{
"matchVariables": [
{
"variableName": "RequestBody"
}
],
"operator": "Contains",
"negationConditon": false,
"matchValues": [
"__proto__"
],
"transforms": []
}
],
"state": "Enabled"
},
{
"name": "NextWithProto",
"priority": 9,
"ruleType": "MatchRule",
"action": "Log",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RequestMethod"
}
],
"operator": "Equal",
"negationConditon": false,
"matchValues": [
"POST"
],
"transforms": [
"Uppercase"
]
},
{
"matchVariables": [
{
"variableName": "RequestHeaders",
"selector": "next-action"
}
],
"operator": "Any",
"negationConditon": false,
"matchValues": [],
"transforms": []
},
{
"matchVariables": [
{
"variableName": "RequestBody"
}
],
"operator": "Contains",
"negationConditon": false,
"matchValues": [
"__proto__"
],
"transforms": []
}
],
"state": "Enabled"
},
{
"name": "NextHeader",
"priority": 10,
"ruleType": "MatchRule",
"action": "Log",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RequestMethod"
}
],
"operator": "Equal",
"negationConditon": false,
"matchValues": [
"POST"
],
"transforms": [
"Uppercase"
]
},
{
"matchVariables": [
{
"variableName": "RequestHeaders",
"selector": "Next-Action"
}
],
"operator": "Any",
"negationConditon": false,
"matchValues": [],
"transforms": []
}
],
"state": "Enabled"
},
{
"name": "NextHeaderLower",
"priority": 11,
"ruleType": "MatchRule",
"action": "Log",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RequestMethod"
}
],
"operator": "Equal",
"negationConditon": false,
"matchValues": [
"POST"
],
"transforms": [
"Uppercase"
]
},
{
"matchVariables": [
{
"variableName": "RequestHeaders",
"selector": "next-action"
}
],
"operator": "Any",
"negationConditon": false,
"matchValues": [],
"transforms": []
}
],
"state": "Enabled"
},
{
"name": "Cve1",
"priority": 20,
"ruleType": "MatchRule",
"action": "Log",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RequestMethod"
}
],
"operator": "Equal",
"negationConditon": false,
"matchValues": [
"POST"
],
"transforms": [
"Uppercase"
]
},
{
"matchVariables": [
{
"variableName": "RequestHeaders",
"selector": "Next-Action"
}
],
"operator": "Any",
"negationConditon": false,
"matchValues": [],
"transforms": []
},
{
"matchVariables": [
{
"variableName": "RequestBody"
}
],
"operator": "Regex",
"negationConditon": false,
"matchValues": [
"\\\"status\\\":\\\"resolved_model\\\""
],
"transforms": []
}
],
"state": "Enabled"
},
{
"name": "Cve2",
"priority": 21,
"ruleType": "MatchRule",
"action": "Log",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RequestMethod"
}
],
"operator": "Equal",
"negationConditon": false,
"matchValues": [
"POST"
],
"transforms": [
"Uppercase"
]
},
{
"matchVariables": [
{
"variableName": "RequestHeaders",
"selector": "Next-Action"
},
{
"variableName": "RequestHeaders",
"selector": "rsc-action-id"
}
],
"operator": "Any",
"negationConditon": false,
"matchValues": [],
"transforms": []
},
{
"matchVariables": [
{
"variableName": "RequestBody"
}
],
"operator": "Regex",
"negationConditon": false,
"matchValues": [
"\\$\\@"
],
"transforms": []
}
],
"state": "Enabled"
},
{
"name": "any",
"priority": 30,
"ruleType": "MatchRule",
"action": "Log",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RemoteAddr"
}
],
"operator": "IPMatch",
"negationConditon": true,
"matchValues": [
"255.255.255.255/32"
],
"transforms": []
}
],
"state": "Enabled"
}
],
"policySettings": {
"requestBodyCheck": true,
"maxRequestBodySizeInKb": 128,
"fileUploadLimitInMb": 100,
"state": "Enabled",
"mode": "Prevention",
"customBlockResponseStatusCode": 403,
"jsChallengeCookieExpirationInMins": 30,
"requestBodyInspectLimitInKB": 128,
"fileUploadEnforcement": true,
"requestBodyEnforcement": true
},
"managedRules": {
"managedRuleSets": [
{
"ruleSetType": "OWASP",
"ruleSetVersion": "3.2"
}
]
}
}
}
]
}
And here is a matching Azure Front Door custom rules configuration in JSON form:
{
"customRules": {
"rules": [
{
"name": "CVE2025_55182_RceProtochain",
"enabledState": "Enabled",
"priority": 1,
"ruleType": "MatchRule",
"action": "Block",
"matchConditions": [
