TL;DR: A newly disclosed denial-of-service vulnerability, CVE-2026-23870, impacts React Server ComponentsΒ and dependent frameworks, including Next.js App Router deployments. The flaw enables unauthenticated attackers to send specially crafted HTTP requests that trigger excessive CPU consumption during request deserialization, leading to potential service degradation or total unavailability. Imperva Threat Research Group has analyzed the vulnerability and associated attack patterns. Imperva Cloud WAF and On-Prem WAF customers are already protected against exploitation attempts targeting this issue.
The Vulnerability
Researchers recently disclosed CVE-2026-23870, a high-severity denial-of-service vulnerability affecting React Server Components and downstream frameworks such as Next.js. The issue exists in how vulnerable React Server Component implementations deserialize attacker-controlled request payloads sent to Server Function endpoints.
The vulnerability stems from improper handling of cyclic or recursively referenced data structures during request processing. Specifically, vulnerable deserialization logic within the React Flight protocol can repeatedly consume maliciously crafted models before properly marking them as processed, resulting in excessive resource consumption.
In practical terms, an attacker can send a specially crafted HTTP request to exposed Server Function endpoints in applications using React Server Components. When the payload is processed, the server enters a high-CPU execution state that can persist for extended periods before eventually throwing an error. Because the error is catchable and the attack requires no authentication, attackers can repeatedly issue malicious requests to sustain denial-of-service conditions.
The issue primarily impacts:
react-server-dom-webpack
react-server-dom-parcel
react-server-dom-turbopack
Affected versions include:
0.0 through 19.0.4
1.0 through 19.1.5
2.0 through 19.2.4
Patched releases are available in:
0.5
1.6
2.5
Because React Server Components are heavily used in modern application architectures, particularly high-traffic ecommerce, SaaS, and API-driven environments, exploitation can have significant operational impact. Applications leveraging Next.js App Router deployments are especially exposed due to the widespread use of Server Function endpoints.
Some of the techniques observed or associated with exploitation include:
Crafted cyclic model payloads designed to trigger recursive deserialization behavior
Repeated requests to Server Function endpoints to sustain CPU exhaustion
Abuse of React Flight protocol request parsing logic
Application-layer denial-of-service attacks targeting availability rather than data theft
Automated scanning of exposed React and Next.js deployments for vulnerable endpoints
Unlike traditional volumetric DDoS attacks, CVE-2026-23870 enables low-bandwidth, application-layer denial of service by forcing disproportionate server-side computation. This makes the attack particularly attractive because relatively small numbers of malicious requests can create significant backend resource exhaustion.
Bottom Line
CVE-2026-23870 highlights the growing security risks associated with modern server-side rendering frameworks and component-driven architectures. By abusing request deserialization logic in React Server Components, attackers can trigger disproportionate backend resource consumption using relatively low-effort HTTP requests.
Since this vulnerability requires no authentication and targets exposed Server Function endpoints directly, exploitation is straightforward in unpatched environments. Organizations using React Server Components, Next.js App Router, or related server-side rendering frameworks should immediately upgrade affected packages and review exposed application endpoints.
Imperva Cloud WAF and On-Prem WAF customers are protected against related attack activity.
Thereβs an automated attack circulating right now that breaks into unprotected Redis servers, takes over the underlying machine, and then carefully puts everything back the way it found it. It restores the database filename. It deletes the tools it used. It detaches from the connections it opened. When itβs done, the server looks healthy. Logs look normal. Nothing appears to be wrong.
Except thereβs a new line in /root/.ssh/authorized_keys that wasnβt there before.
We discovered this attack recently targeting a single Redis honeypot. Attacks came from 10 distinct source IPs across six countries, and over 1,200 attack attempts were recorded in a single month. Our data-driven, AI-based honeypot enabled us to detect and analyze this activity in detail.
The Attack
Redis was never designed to face the internet directly. But people expose it: a misconfigured security group, a container with the wrong port mapping, a developer who needs it reachable for a quick test. The default configuration has no password. Port 6379, open to the world.
When our Redis honeypot instance was exposed, the first visitors arrived within minutes. They connected, ran INFO, read the version string, and disconnected. Thatβs it. They arenβt trying to break in. Theyβre taking a census- cataloging whatβs out there, how old it is, whether itβs protected. Thousands of these scans happen every day across the internet, quiet and mechanical.
Then a second wave showed up. These bots tried something: config set dbfilename backup.db. Itβs a test. If Redis accepts the command, it means the server will let you write files to arbitrary paths on the host machineβs disk. The bot doesnβt exploit this. It just records the address and leaves. Itβs building a list for someone else.
The real attack came as a single connection that tried five different methods of compromise in rapid sequence. The whole thing took a few seconds. It opened with FLUSHDB to wipe the database and clear the slate, and then worked through the following tricks:
Cron injection: redirect Redisβs save directory to /var/spool/cron/, write a key whose value is a cron entry. Now the host downloads and runs a binary from a C2 server every minute, with a randomly generated filename to dodge signature detection.
Lua sandbox escape: a Debian/Ubuntu packaging decision dynamically linked Redisβs Lua interpreter against the system library, breaking the sandbox. One EVAL command loads io.popen, leading to full RCE. CVE-2022-0543 is four years old, yet still working.
SSH key planting: same file-writing trick, pointed at /root/.ssh/authorized_keys. One line, and the operator has root access forever.
Replication hijacking: SLAVEOF tells Redis to sync from the attackerβs server, which serves a malicious shared object disguised as a database dump. MODULE LOAD turns it into a Redis extension exposing system.exec. This trick leads to full RCE through Redisβs own replication protocol.
Direct execution: use that module to download and run the binary through the shell.
Five methods, one connection, a few seconds- but attackers donβt need all five to work. They just need one.
Then the connection did something unexpected. It started cleaning up.
SLAVEOF NO ONE
Β system.exec "rm -rf /tmp/exp.so"
Β MODULE UNLOAD system
Β config set dbfilename dump.rdb
It detached from the rogue replication server. It deleted the malicious shared library from the disk. It unloaded the module from Redis. It restored the original database filename. Redis is often used for ephemeral data, like sessions, queues, and rate limits, so a cleared database might not even raise an alarm. It just looks like a restart.
The attack was optimized for staying hidden after breaking in. Every forensic trace is reversed. The only artifact left behind is an SSH public key, one line in a file that most administrators never read, indistinguishable from a legitimate entry. Even if you find the malware, kill the process, and delete the cron entry, the key is still there. Root access, on demand, forever. Or until someone manually audits authorized_keys, which is rare.
The Botnets
The SSH Key Operator: A sophisticated, single-operator attack that targets unprotected Redis servers. It attempts five different RCE methods. Over a single month, our single Redis honeypot recorded over 1,200 attack attempts from 10 distinct source IPs across six countries. The majority included RCE attempts: Lua sandbox exploits and replication hijacking aimed at arbitrary command execution on the host. Different C2 servers, different binary names, but the same sequence, the same Lua payload, the same SSH public key. One operator, rotating sources and randomizing filenames. The key is the only constant.
The traffic came in distinct waves. Baseline was roughly 15 to 20 attempts per day from two or three sources. Then, without warning, a wave would hit, with a single IP connecting hundreds of times in an afternoon, once every 69 seconds- in total, over 300 attempts in a few hours. We saw three to four waves per month, each lasting two to six hours, each from a different source IP. Then silence until the next wave.
MGLNDD Botnet: A separate operation that periodically connects to exposed Redis servers, sending a single command format (MGLNDD_54.147.241.42_6379) to perform a βroll callβ β checking whether the Redis server is already part of their botnet. It operates from Azure VMs using AWS IP addresses, never repeating the same source twice.
The SSH key operator and the MGLNDD botnet share the same hunting ground but ignore each other completely. Two separate operations are working in the same territory. An exposed Redis port isnβt just targeted by an attacker, itβs targeted by an ecosystem.
Takeaway
The attack is silent. The window between βIβll fix that config laterβ and the machine is silently compromised isnβt days or hours-itβs seconds. Everything looks fine afterward: the server is up, the application works, the dashboards are green. The only artifact is an SSH key, patient and persistent, waiting to be used.
What You Must Do:
Never expose Redis to the internet. Restrict access via security groups, firewalls, or VPCs.
Set a strong Redis password. The default has none.
Regularly audit /root/.ssh/authorized_keys for unfamiliar keys-attackers hide persistence here.
Keep Redis patched. CVE-2022-0543 still works after 4 years.
Monitor for suspicious commands: CONFIG SET, MODULE LOAD, FLUSHDB, SLAVEOF.
Use file integrity monitoring on /root/.ssh/authorized_keys to detect tampering.
Donβt trust green dashboards. Assume youβve been breached until verified otherwise.
Imperva Data Security solutions provide comprehensive protection for your data against a wide range of threats. These offerings enable security teams to identify the location of sensitive information, monitor access patterns, and detect misuse promptly to facilitate timely response.
Unit 42 uncovers high-risk AI browser extensions. Disguised as productivity tools, they steal data, intercept prompts, and exfiltrate passwords. Protect your browser.
CVE-2026-41940 is a critical authentication bypass vulnerability affecting cPanel & WHM, including DNSOnly, in versions after 11.40. The flaw, discovered by WatchTowr Labs, exists in the login flow and allows unauthenticated remote attackers to gain unauthorized access to the control panel. The vulnerability carries a CVSS 3.1 score of 9.8 and is classified under CWE-306: Missing Authentication for Critical Function.
cPanel & WHM is widely used to manage web hosting environments. WHM provides administrative access to hosting infrastructure, while cPanel gives individual account holders control over their hosted sites. Because this vulnerability affects the authentication layer of a management interface, successful exploitation could give attackers access to high-value administrative functions across hosting environments. The issue affects all currently supported versions of cPanel & WHM, and the flaw is tied to session loading and saving behavior.
cPanel has released patched versions and recommends immediate updates. Administrators should update a fixed version, verify the cPanel build, and restart the cPanel service. For environments that cannot immediately patch, cPanel recommends blocking inbound traffic on ports 2083, 2087, 2095, and 2096 or temporarily stopping affected services.
Imperva customers are protected out-of-the-box against CVE-2026-41940.
Observations from Our Data
Since the release of CVE-2026-41940, Imperva has observed nearly 4,000 attack requests targeting customer environments.
Our data shows:
Attacks targeting sites across 15 distinct industries and 17 countries, indicating broad scanning and opportunistic exploitation rather than activity concentrated against a single vertical or geography.
US-based sites accounted for almost 70% of observed attacks, followed by Barbados and Israel. The heavy concentration against US sites suggests attackers are prioritizing regions with large hosting and web infrastructure footprints, while the presence of smaller geographies indicates automated discovery across exposed internet-facing assets.
The most frequently targeted industries were Business, Society, and Education. This distribution reflects the broad deployment of hosting control panels across organizations that maintain public-facing websites, portals, and distributed web infrastructure.
While observed volume remains limited compared to mass exploitation campaigns, the spread across industries and countries shows active probing for exposed cPanel and WHM instances. Given the vulnerabilityβs unauthenticated nature and impact on administrative access, even moderate request volumes warrant urgent attention, and attack volumes will likely grow.
Mitigation and Protection
The definitive remediation for CVE-2026-41940 is to update cPanel & WHM to a patched version immediately. Organizations should also review cPanelβs detection guidance, inspect session files for indicators of compromise, and audit WHM access logs for unauthorized activity. cPanelβs advisory specifically recommends purging affected sessions, forcing password resets for root and WHM users, and checking for persistence mechanisms if indicators of compromise are found.
Imperva customers using Cloud WAF and WAF Gateway are protected against exploitation techniques associated with CVE-2026-41940. Impervaβs web application firewall inspects HTTP traffic for malicious patterns, helping block attempts to abuse authentication workflows and session-handling behavior before they reach vulnerable systems.
For customers with Cloud WAF, protection is automatically applied. Customers with WAF Gateway should refer to the manual mitigation guide sent by Imperva support teams and provided in the Imperva Community Guide.
Conclusion
CVE-2026-41940 represents a critical risk for organizations running exposed cPanel & WHM infrastructure. Its combination of unauthenticated access, low attack complexity, and potential administrative impact makes it a high-priority vulnerability for patching, monitoring, and incident review.
Imperva customers are protected against exploitation attempts associated with this vulnerability through Impervaβs web application firewall protections and HTTP traffic inspection capabilities. Organizations running cPanel & WHM should still apply vendor patches immediately, validate their deployed versions, and review available logs and session artifacts for signs of compromise.
When Anthropic unveiled Mythos and Project Glasswing, the reaction was immediate and polarized. Some dismissed it as fear-driven marketing, while others treated it as a credible shift in the threat landscape.
Like with many things, the truth is probably somewhere in the middle. I wanted to test that for myself, and since I recently got access to OpenAIβs Trusted Access for Cyber program, I decided to take it for a spin.
GPT-5.4 identified the bugs and helped assemble a working exploit chain, but it wasnβt a simple βbuild me an exploitβ prompt. Guiding it required domain knowledge, iterative probing, and knowing which paths were actually exploitable.
On modern browsers like Safari, exploitation is less about finding bugs and more about finding bugs that still matter after multiple layers of defense.
The bug Iβm going to talk about today sits in a more interesting category. The bug itself looked contained, and in many ways it was. It did not provide a path to RCE or a sandbox escape. What it did instead was cross a different boundary entirely: it broke the Same-Origin Policy.
If you visited a malicious page from any Apple device, it could read authenticated cross-origin data from other sites you use, including access tokens and other sensitive data, making account takeover trivial.
The video below shows the PoC we sent Apple, demonstrating leakage of sensitive data from both Apple Connect and iCloud / Apple ID endpoints. Although this demo focuses on Apple services, the issue affects all websites. This means that by visiting a malicious website, sensitive data from other domains is at risk of being leaked.
The Sandbox Russian Doll
Browser exploitation in 2026 is a lot like being trapped in a Russian doll.
You start in the smallest doll, and every time you escape one layer you discover you are still trapped inside another one.
Finding a low-level memory bug is not the same thing as finding an exploit. Most of these bugs die in the gap between βmemory corruption happenedβ and βsomething meaningful crossed a security boundary.β
On the outside you have the browser process model. Even if renderer code goes wrong, the browser is trying very hard to keep that damage inside the web content process.
Inside that you have the web security model: Same-Origin Policy, CORS, opaque responses, cookie scoping, and credential modes. Even if a page can trigger a cross-origin request, the renderer, and especially the Gigacage, should not be able to access the response bytes. Right?β¦
The Bug
The original bug lives in the refresh logic for non-shared resizable WebAssembly memory.
When a non-shared WebAssembly.Memory grows in BoundsChecking mode, JavaScriptCore can replace the underlying memory handle. That part is not the bug. The bug is what happens after that to the JS-visible resizable buffer returned by memory.toResizableBuffer().
The bug is simple enough that once I saw it, it was hard to unsee it. Safariβs grow path effectively does this:
And the refresh step effectively does this:
After memory.grow(), WebKit updates the buffer metadata, but leaves m_data pointing at the old freed allocation.
So after a grow, JavaScript can hold a buffer whose reported size is new, whose handle is new, but whose actual data pointer still references the old freed Primitive Gigacage allocation.
That turns into a stale typed-array window over freed memory.
On its own, this is already a real bug. But weβre still stuck inside the JavaScriptCore gigacage, effectively sandboxed. Without a second bug to break out into the renderer, it doesnβt chain into anything meaningful. What we have is a solid first-stage primitive, but no real security impact on its own.
Why it did not look exploitable at first
The stale window is confined to the Primitive Gigacage, which immediately limits what you can do with it. Many typical targets either never land there, lack useful structure, or fail to produce any cross-boundary effect.
So early on, it had all the hallmarks of a bug that looks promising but rarely goes the distance:
easy source-level root cause
visible stale memory behavior
real reclaim
no clean escape path
This is where a lot of low-level browser bugs die.
What changed the problem was a very different framing: maybe I did not need to escape the cage at all.
Maybe I just needed the browser to place something valuable inside it.
The Pivot
Instead of asking βhow do I get from my stale WASM view to some protected browser state?β I started asking a better question:
βWhat browser code takes data that JavaScript is not allowed to read, but still copies that data into normal renderer memory?β
Because that is all I need.
I donβt need to break the abstraction.
I just need the browser to break it for me.
That naturally narrows the search space to subsystems that:
handle sensitive cross-origin data, and
still allocate ArrayBuffer-backed memory as part of their internal pipeline
That points straight at Fetch. The Fetch API clearly indicates that the response is opaque, meaning that its headers and body are not available to JavaScript.
Opaque Responses Are Supposed to Be Opaque
At the API level, the Fetch model here is straightforward.
The browser may send the request, including cookies depending on context, but JavaScript receives an opaque response.
That means:
I can hold the Response object
but I cannot read the body bytes
And WebKit enforces that in the obvious place:
FetchBodyOwner::readableStream() blocks opaque bodies via isBodyNullOrOpaque().
So at first glance, everything looks fine. The body is hidden. The policy is enforced. Same-Origin Policy survives another day.
Except it does not.
The Fetch Behavior that Broke the Modal
The surprising part is Response.clone().
If FetchResponse::clone() is called while the response is still loading, WebKit will internally create a readable stream so it can tee the body between the original response and the clone.
That internal path does not apply the same opaque-body check first.
And once that happens, hidden response bytes start becoming very real renderer objects.
This is the part that made me stop and stare at the source, because the mismatch is right there.
The normal body path blocks opaque responses:
But FetchResponse::clone() does this while the response is still loading:
That is why it works.
The visible accessor path says βopaque bodies do not get a stream.β The clone path says βif it is still loading, create a stream so both clones can tee it.β
That second path is exactly what I needed.
The data flows through normal ArrayBuffer creation paths:
buffered chunks go through tryCreateArrayBuffer()
later chunks go through takeAsArrayBuffer()
shared buffer data gets copied into ordinary ArrayBuffer allocations inside the renderer
So the policy ends up split in two:
the public Fetch API says the body is opaque
the renderer still materializes the opaque body into readable byte arrays during clone-time streaming
Combined with the stale WASM window, it becomes a SOP break.
The Chain
At a high level, the exploit became:
Force the target WASM memory into the BoundsChecking path.
Call memory.toResizableBuffer().
Grow the memory.
Keep the stale resizable buffer whose pointer still targets freed Primitive Gigacage pages.
Trigger a cross-origin fetch(β¦, { mode: βno-corsβ, credentials: βincludeβ }).
Call response.clone() while the response is still loading.
Let Fetch internals materialize the hidden body bytes into ordinary renderer ArrayBuffers.
Reclaim the stale WASM-covered pages with those allocations.
Read the cross-origin bytes through the stale view.
That is the entire trick.
I never needed response.text(). I never needed response.arrayBuffer(). I never needed the public API to hand me the body.
The browser copied the body into memory for its own internal bookkeeping, and the stale WASM view read it directly.
That is why this bug stopped being βsome weird WASM UAFβ and became βthis completely breaks the Same-Origin Policy.β
The file:// Detour
One of the weirdest parts of the research was that the request side behaved differently depending on where I launched it from.
In my testing, cross-origin requests were much easier to get moving from file:// than from a normal https attacker page.
That sounds backwards until you look at WebKitβs handling of local origins.
Document.cpp has explicit special-casing around local documents and settings like:
allowUniversalAccessFromFileURLs
allowFileAccessFromFileURLs
MiniBrowser exposes those knobs too, which made file:// very useful as a research environment. It let me focus on the memory side and confirm the leak path before I had a clean web-facing story.
But I did not want a local-file party trick.
I wanted a real web exploit.
And from a normal https page, the same request pattern was not giving me the reliability I wanted.
That is where about:blank saved me.
Why about:blank saved the final POC
The final PoC opens an about:blank popup and performs the fetches from there:
This ended up mattering a lot.
At first I thought this was just an origin-inheritance trick. That part is real:
So about:blank does inherit the openerβs origin.
But that alone does not explain why the popup path behaved differently.
What actually seems to matter is Safariβs cookie / first-party bookkeeping. Fetch subresource requests copy document->firstPartyForCookies() into the request:
And WebKitβs cookie blocking logic bails out immediately if that first-party domain is empty:
That is a very different path from a normal attacker-controlled https page. From a regular https://attacker.example origin, the first party is the attacker site, so a request to the victim site looks third-party and Safariβs tracking-prevention logic can suppress cookies.
From the about:blank popup path, the security origin still comes from the opener, but the popupβs top-level URL / first-party context is no longer a normal registrable https site in the same way. In practice, that was enough to make credentials: βincludeβ requests behave differently and get me the authenticated traffic pattern I needed.
So the important point is not βabout:blank disabled CORS.β It did not. The important point is:
the popup kept the openerβs origin
the request still went through normal Fetch/CORS code
Safariβs first-party cookie logic treated that popup context differently
That was the difference between βcross-origin request happens but is uselessβ and βcross-origin request comes back with authenticated bytes worth stealing.β
Why this was fun
This is my favorite kind of browser bug.
Not because the root cause was complicated. It was not. The WASM bug was almost embarrassingly direct.
And not because the final chain was huge. It was not.
It was fun because it is exactly the kind of bug modern browser architecture is supposed to suppress.
A stale pointer inside a cage is supposed to stay a stale pointer inside a cage.
An opaque response is supposed to stay opaque.
Those are both reasonable assumptions.
The exploit works because both assumptions were true only locally.
JavaScriptCore gave me a stale view that looked hard to use. WebCore Fetch gave me sensitive bytes that looked impossible to read.
Put them together and Safariβs Same-Origin Policy fell apart.
Disclosure
We reported our findings to Apple. Shortly after, a fix shipped, suggesting the issue was already known internally.
The vulnerability (CVE-2026-20664) is addressed in iOS 26.4 and iPadOS 26.4 (23E6254 and later), and macOS Tahoe 26.4 (25E253 and later). Make sure your systems are up to date.
Closing Thoughts
The biggest thing on my mind after working with these models is the leverage they provide, and what that means for N-days. A security patch in popular software used to hide the underlying exploit behind time, effort, and expertise. Now that you can scale tokens instead of effort, that barrier is mostly gone.
This doesnβt turn exploitation into a trivial task. You still need someone who understands what they are looking at, can filter noise, and can steer the process when it stalls. But AI changes the unit of work. Instead of deep, sequential effort, you get parallel exploration and rapid iteration. The constraint shifts from raw effort to how effectively an operator can guide multiple lines of inquiry at once.
`
Unit 42 reveals how multi-agent AI systems can autonomously attack cloud environments. Learn critical insights and vital lessons for proactive security.
The recent buzz aroundΒ AnthropicβsΒ MythosΒ model has been intense, and for good reason. Early reports suggest a model that significantly advances automated reasoning over large codebases, vulnerability discovery, and exploit generation. Some are already calling it a βgame changerβ for offensive security.Β
But like most breakthroughs in AI, the reality is more nuanced.Β
LetβsΒ unpack what Mythos is, whyΒ itβsΒ getting so much attention, and where the real impact will (andΒ wonβt) be.Β
What Is Mythos, and Why It MattersΒ
At its core, Mythos is designed toΒ operateΒ deeply within software systems:Β
It can reason acrossΒ entire codebases, not just snippetsΒ Β
MythosΒ appearsΒ to push beyond that,Β closer to what human security researchers do when analyzing complex systems.Β
ThatβsΒ the hype.Β NowΒ letβsΒ put it into perspective.
1. Closed Systems Still Have a Natural Advantage
One of the most important constraints,Β often overlooked,Β isΒ access.Β
Organizations running:Β
Licensed binariesΒ Β
Closed-source productsΒ Β
SaaS platformsΒ Β
are inherently less exposed to this class of AI-driven analysis.Β
Why? Because MythosΒ appears to beΒ most effective when it hasΒ full visibility into the source code. Without that:Β
Reverse engineering binaries is stillΒ hard and lossyΒ Β
SaaS environments expose onlyΒ interfaces, not logicΒ Β
This creates aΒ natural barrierΒ for attackers.Β
Although βsecurity through obscurityβΒ isnβtΒ a solution, in practice:Β
Open-source projects and exposed codebases will feel the impact firstΒ Β
Closed vendors still need to worry, butΒ theyβreΒ not suddenly transparent overnightΒ
2. The Real Pressure Point: Time-to-Mitigation
AIΒ doesnβtΒ just changeΒ whatΒ attackers canΒ do,Β it changesΒ how fastΒ everything happens.Β Β
And this is whereΒ securityΒ vendorsΒ feel the most pressure.Β TheΒ challengeΒ isnβtΒ whether vulnerabilitiesΒ exist,Β itβsΒ how fastΒ vendorsΒ can respondΒ onceΒ theyβreΒ discovered.Β
The new race:Β
AI/ humanΒ finds vulnerability βΒ Β
AIΒ Exploit is generated quickly βΒ Β
Attack trafficΒ emergesΒ earlier βΒ Β
Defenses must adapt in near real-time.
This shifts the competitive advantage to vendors that can:Β
AutomateΒ security workflows toΒ
RapidlyΒ understand new attack patternsΒ Β
Generate mitigationsΒ Β
Deploy protectionsΒ before mass exploitationΒ
3. The Budget Reality: AI Red-Teaming Isnβt CheapΒ
One of the least discussed aspects of Mythos isΒ cost.Β
Running such a model at scale involves:Β
High compute costsΒ Β
Expensive infrastructureΒ Β
For example, Anthropic admitted that βAcross a thousand runs through our scaffold, the total cost was under $20,000β for finding vulnerabilities in OpenBSD.
Significant human validation effortΒ
And that last part is critical.Β
Every finding still requires:Β
Verification (is itΒ real?)Β Β
ReproductionΒ Β
Impact assessmentΒ Β
Which means moreΒ security engineers per finding, not less.
Organizations will need to start budgeting for:Β
AI-assistedΒ red teamingΒ Β
Dedicated pipelines to process findingsΒ Β
Integration into SDLC workflowsΒ Β
This mirrors what weβve already seen withΒ GitHub Copilot-style assistants and AI-based code analysis tools.
Implication for attackers:Β
These βdoomsdayβ capabilities areΒ not evenly distributed.Β
Otherwise, teams risk wasting cycles on low-quality reports and missing real vulnerabilities buried in noise. Ironically, AI willΒ be neededΒ to defend against AI-generated reports.
5. Not All Vulnerabilities Are Equal
Another important nuance:Β Β
Finding a vulnerability β exploiting it at scale.Β
Even with Mythos:Β
Many findings will beΒ low impactΒ Β
Exploitation may requireΒ environmentΒ specific conditionsΒ Β
Real-world constraints (auth, rate limits, monitoring) still applyΒ Β
This is where traditional security layers still matter:Β
TheΒ MythosΒ model presentsΒ a meaningful step forward. It brings AI closer to acting like a real security researcher, capable of deep reasoning and complex analysis.Β
ButΒ itβsΒ not a universal βbreak everythingβ button.Β
Operational processes (triage, mitigation) become the real bottleneckΒ Β
The hype focuses onΒ capability.Β The reality is aboutΒ constraints and execution.Β
And as always in cybersecurity, the winners wonβt be those with the best tools, but those who can operationalize speed, from detection to mitigation, at scale.Β
In this article, we disclose a new high severity unauthenticated remote denialβofβservice vulnerability we identified and reported in React Server Components that weβve dubbed βReact2DoSβ. Β In this blog, weβll analyze its impact and place it in the broader context of recently found Flight protocol vulnerabilities, especially CVEβ2026β23864.
Introduction
We are in a phase of the web where performance and developer experience are no longer trade-offs, theyβre expectations. Modern frameworks compete to ship less JavaScript, reduce client-side complexity, and move logic back to the server.
React, as one of the dominant forces in frontend development, has been at the forefront of this evolution. With the introduction of React Server Components (RSC), the ecosystem embraced a new model: components that execute exclusively on the server, access databases and secrets directly, and stream a serialized UI representation to the client.
This architecture promises smaller bundles, cleaner separation of concerns, and more efficient rendering. Instead of hydrating everything on the client, Server Components emit a structured stream that the browser reconstructs locally.
At the heart of this mechanism lies a custom streaming protocol known as Flight. Through Flight, React can serialize complex structures, like arrays, maps, object references, even promises and async boundaries, allowing the server to describe rich UI trees in a compact format.
This is powerful.
But history has shown that when we introduce custom serialization formats and complex parsers, we also introduce risk. The server must deserialize and reconstruct object graphs from client-controlled input. And complex parsing logic has long been fertile ground for vulnerabilities.
In our research we discovered a denial-of-service vulnerability that allows an attacker to impose disproportionate computation to the remote server.
React2Shell and subsequent DoS vulnerabilities
Earlier this year, the disclosure of React2Shell caught much of the community off guard, triggering emergency patches and intense scrutiny of the React Server Components architecture, amplified by waves of low-quality AI-generated analysis that blurred the line between verified facts and speculation. This episode also prompted deeper investigations into and led to new discoveries related to the security of the Flight protocol and related parsing mechanisms.
CVEβ2026β23864 (CVSS 3.1 of 7.5), stood out as a notable example and serves as a useful reference for understanding the mechanics behind the issue we explore in this research.
Among other vectors, this vulnerability concerned the BigInt deserialization path in Flight:
$n markers denote BigInt values
No limit was enforced on digit length
Therefore, sending a millionβdigit BigInt could cause a significant computation cost, and CPU exhaustion. An example payload could look like this:
0:"$n9999999999...[repeated 1 million times]"
In our setup, a single query like this could delay the serverβs execution by several seconds if the inbound payload reaches the maximum allowed size (1MB with Node.js runtime, 10MB with Edge runtime).
This was the starting point of our research, and we tried to find payload that would trigger a similar, or superior cost to the server. This is exactly what we found, actually more computationally-intensive Β by several orders of magnitude.
React2DoS
React relies on a mechanism known as the React Flight Protocol to serialize values that are sent to Server Functions.
On the client side, data is transmitted to the server as small pieces (or βchunksβ), for example through form submissions:
As illustrated above, these chunks can reference one another.
After deserialization on the server, the reconstructed object looks like this:
{ "category": "vehicle", "model": "tesla" }
At first, we tried to measure the cost of execution of every type of reference supported by the Flight protocol. Among them, we looked at two promising ones: $Q and $W, respectively instantiating new Maps and Sets from the client request payload.
The first observation we made was that it was possible to reference the root element in the root element itself (!), which paved the way to recursive expressions:
β0β : [β$Q0β]
This, would cause the execution of the following JavaScript expression:
New Map([null])
Which makes perfect sense, because at the time of resolution of $Q0, $0 is not known yet.
However, what surprised us, was the fact that the following expression:
did trigger the execution of the Map constructor n times!
Indeed, the ReactFlightReplyServer uses a `consumed` attribute to prevent multiple computations of the same reference and prevent abuse. But this mechanism only enters in action when the reference is successfully resolved (see Fig 1).
Fig. 1: Exception doesnβt prevent recomputation of the same faulty MapΒ
Because the `new Map` expression failedΒ (new Map([null])Β isΒ not a validΒ JavaScript expression), this outcome was not stored anywhere.Β ButΒ surprisingly,Β the deserializationΒ is not interrupted byΒ thisΒ exception!Β
The execution ofΒ the expressionΒ `new Map ([null])`Β is prettyΒ cheap,Β it takes our serverΒ aroundΒ 0.03ms.Β Virtually instant.Β ButΒ thisΒ isΒ neglectingΒ the factΒ thatΒ Β aΒ threatΒ actorΒ canΒ insert more than 100,000 instancesΒ inΒ a 1MB payload,Β leading toΒ theΒ cost of several seconds, comparable to the CPU exhaustion issue behindΒ CVEβ2026β23864Β and described above.Β
Considering this, weΒ submittedΒ a first report to Meta, sharing thisΒ POCΒ andΒ demonstratingΒ the impact.Β
But soon after, we realized there was a wayΒ more impactful payload we could generate by exploiting our original idea.Β Β
Instead of sending a series of β$Q0β that would immediately trigger the exception, we decided to introduce a series of valid map entries at the start of the root entry, to force the Map constructor to iterate over them before triggering the expected exception (see Fig. 2).Β
Fig. 2: Internal recursive resolution of β$0βΒ
By doing so, we achieved a quadratic complexity, and a much more expensiveΒ payloadΒ !Β TheΒ optimalΒ number setting is n/2 valid maps and n/2Β map references to the 0 objectΒ (β$Q0β).Β
CVEβ2026β23864Β (CPU exhaustion) vs React2DoSΒ (CVE-2026-23869)Β
WithΒ ourΒ newΒ attackΒ vector,Β theΒ computationΒ couldΒ easilyΒ last several minutes.Β Therefore, with only small payloads ofΒ tens ofΒ kilobytes, it was possible toΒ initiateΒ impactfulΒ DoS attacks.Β
To give ourselves an idea of the impact of this attack vector, weΒ computedΒ a chart showing the comparison betweenΒ CVEβ2026β23864 (CPU exhaustion) and React2DoS. The result showed that after only a few kilobytes, React2DoS starts to stand out, and when the payload size reaches hundreds of kilobytes, it is already more powerful by several orders of magnitude (see Fig. 3).Β
Therefore, with a single request, a threat actor can trigger a computation that will take minutes to handle. By repeating this, complete denial of service can be achieved.Β
MitigationΒ
The React team fixed this issueΒ via setting the consumed flag before any map/set constructor was called.
The issue affectsΒ ReactΒ Server ComponentsΒ versionΒ 19.2.4 and below.Β We recommend that youΒ update toΒ the latest available version that patches this vulnerabilityΒ as soon as possible.Β Β
If your application already sits behind an Imperva proxy, it is automatically protected against this attack.Β
ConclusionΒ
This case highlights an importantΒ reality:Β the path to innovation inevitably introduces complexity, and therefore risk. As ecosystems evolve rapidly, staying up to date andΒ remainingΒ aware of newly discovered security issues is essential.Β
In a more personal way, it was a pleasure for me to delve into one of the most usedΒ frameworkΒ in the world andΒ discoverΒ a finding with meaningful impact. ThisΒ wouldnβtΒ have been possible ifΒ researchers beforeΒ didnβtΒ pave the way withΒ their investigations andΒ their recent findings (React2Shell,Β Β CVEβ2026β23864β¦).Β Β
DisclosureΒ TimelineΒ
FebΒ 3Β 2026Β βΒ Report including firstΒ payloadΒ
Unit 42 uncovers escalating Kubernetes attacks, detailing how threat actors exploit identities and critical vulnerabilities to compromise cloud environments.
Unit 42 research on multi-agent AI systems on Amazon Bedrock reveals new attack surfaces and prompt injection risks. Learn how to secure your AI applications.