❌

Normal view

Hacking Safari with GPT 5.4Β 

23 April 2026 at 20:58

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.

infographic

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().

diagram

The bug is simple enough that once I saw it, it was hard to unsee it. Safari’s grow path effectively does this:

code1

And the refresh step effectively does this:

code2

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.

If I do a cross-origin request with:

fetch(url, { mode: β€œno-cors”, credentials: β€œinclude” });

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:

code3

But FetchResponse::clone() does this while the response is still loading:

code4

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:

  1. Force the target WASM memory into the BoundsChecking path.
  2. Call memory.toResizableBuffer().
  3. Grow the memory.
  4. Keep the stale resizable buffer whose pointer still targets freed Primitive Gigacage pages.
  5. Trigger a cross-origin fetch(…, { mode: β€œno-cors”, credentials: β€œinclude” }).
  6. Call response.clone() while the response is still loading.
  7. Let Fetch internals materialize the hidden body bytes into ordinary renderer ArrayBuffers.
  8. Reclaim the stale WASM-covered pages with those allocations.
  9. 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:

code5

This ended up mattering a lot.

At first I thought this was just an origin-inheritance trick. That part is real:

code6

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:

code7

And WebKit’s cookie blocking logic bails out immediately if that first-party domain is empty:

code8

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.
`

The post Hacking Safari with GPT 5.4Β  appeared first on Blog.

Anthropic Mythos: Separating Signal from Hype

14 April 2026 at 19:43

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Β Β 
  • ItΒ demonstratesΒ strong capabilities inΒ multi-step vulnerability discoveryΒ Β 
  • It can potentially chain findings intoΒ realistic exploit pathsΒ Β 

This is what sets it apart from earlier models. Traditional LLMs often struggled with:Β 

  • Context fragmentation (limited memory of large systems)Β Β 
  • Superficial pattern matching (vs. true reasoning)Β Β 
  • Weakness in multi-stage attack logicΒ Β 

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.Β 

  • Well-funded actors (nation-states, top-tier cybercrime groups) β†’Β likely adoptersΒ Β 
  • Opportunistic attackers β†’ much slower to benefitΒ Β 

SoΒ the threat landscapeΒ widens at the top, not uniformly across all attackers.

4. Bug Bounty Programs Will Feel the Noise First

One immediate and very practical impact: bug bounty platforms are about to get noisy.Β 

Expect a surge of:Β 

  • AI-generated vulnerability reportsΒ Β 
  • Poorly validated findingsΒ Β 
  • Duplicates and false positivesΒ Β 

This creates a scaling problem for security teams.Β 

Organizations will need to adapt:Β 

  • StrongerΒ triage filtering mechanismsΒ (likely AI-driven)Β Β 
  • Reputation systems for researchersΒ Β 
  • Penalties for repeated false positivesΒ Β 
  • PotentialΒ adjustments in bounty pricingΒ Β 

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:Β 

  • WAF,Β APIΒ protection,Β BotΒ protectionΒ 
  • Identity protectionΒ 
  • Data protectionΒ 
  • Threat reputationΒ 

MythosΒ increasesΒ discoveryΒ capability, butΒ doesn’tΒ eliminateΒ defenseΒ inΒ depth.Β 

Final ThoughtsΒ 

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.Β 

  • Closed systems still provide frictionΒ Β 
  • Costs limit widespread misuseΒ Β 
  • Defensive technologiesΒ remainΒ highly relevantΒ Β 
  • 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.Β 

The post Anthropic Mythos: Separating Signal from Hype appeared first on Blog.

React2DoS (CVE-2026-23869): When the Flight Protocol Crashes at Takeoff

9 April 2026 at 16:54

Executive Summary

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:

payload = {
Β  "0": (None, '["$1"]'),
Β  "1": (None, '{"category":"vehicle","model":"$2:modelName"}'),
Β  "2": (None, '{"modelName":"tesla"}'),
}

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:

β€œ0” : [β€œ$Q0”, β€œ$Q0” ..., β€œ$Q0”] (x n)

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).

Screenshot 2026 04 09 at 7.46.50 AM

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).Β 

Screenshot 2026 04 09 at 7.47.57 AM

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).Β 

Screenshot 2026 04 09 at 7.49.09 AM

Fig. 3: Comparison React2DoS – CVE‑2026‑23864Β 

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Β 

FebΒ 5Β 2026 – Second payload reportedΒ 

April 8Β 2029 – Vulnerability fixed in 19.2.5 (patch backported to versions 19.0.5, 19.1.6)

The post React2DoS (CVE-2026-23869): When the Flight Protocol Crashes at Takeoff appeared first on Blog.

Cracks in the Bedrock: Escaping the AWS AgentCore Sandbox

8 April 2026 at 00:00

Unit 42 uncovers critical vulnerabilities in Amazon Bedrock AgentCore's sandbox, demonstrating DNS tunneling and credential exposure.

The post Cracks in the Bedrock: Escaping the AWS AgentCore Sandbox appeared first on Unit 42.

N8N: Shared Credentials and Account Takeover

3 March 2026 at 23:41

Executive Summary

We identified a security weakness in n8n’s credential management layer that could have completely compromised the application’s security. This finding highlights the core risks of centralized authentication in workflow automation platforms.

As n8n serves as the central hub connecting critical systems and orchestrating business processes across teams, any gap in credential handling can potentially cascade across connected systems, disrupting operations, compromising data flows, and credentials.

While this issue was fixed in v2.6.4, it reminds us about the unique security challenges of AI automation platforms.

Introduction

We are in a moment where AI and automation platforms are rapidly becoming embedded in everyday operations, allowing teams to connect models, APIs, SaaS tools, and internal systems with minimal friction.

Platforms like n8n promise powerful automation through visual workflows and reusable credentials, lowering the barrier to orchestrating complex tasks across services. But this convenience comes with structural risk: these tools centralize highly sensitive tokens, OAuth flows, and API keys, effectively concentrating trust in a single automation layer.

When that layer fails to enforce basic security controls, the impact is not limited to one workflow, it can extend across every connected system. In this research, we examine how a Stored XSS vulnerability in n8n’s OAuth credential handling can lead to account takeover and broader instance compromise.

The Vulnerability

The vulnerability lies in how n8n handles the β€œAuthorization URL” within the OAuth credential setup. OAuth (Open Authorization) is an authorization framework that allows an application to access a user’s data on another service without exposing the user’s password.

In a standard workflow, users configure OAuth credentials to authenticate n8n with an external provider. When a user clicks β€œConnect my account,” n8n opens a popup window pointing to the service’s authorization page.

However, we discovered that the frontend function responsible for opening this window did not validate the protocol of the provided URL (see below). This allowed an attacker to bypass the expected scheme and inject JavaScript code.

The Attack Flow

Because n8n allows credentials to be shared between users in the same instance (collaborative features), a threat actor can weaponize this weakness, see Fig 1.

Screenshot 2026 03 03 at 11.23.08 AM

Fig. 1: High level view of the attack flow

The steps are the following:

  1. Preparation: The attacker creates a new credential using the β€œOAuth2 API” type.
  2. Injection: In the β€œAuthorization URL” field, instead of a valid URL, the attacker inserts a malicious JavaScript payload.
  3. Trap: The attacker shares this credential with the victim (e.g., an administrator or a user with higher privileges).
  4. Execution: The victim, seeing a shared credential, opens it and clicks β€œConnect my account.” The browser immediately executes the injected JavaScript in the context of the victim’s session instead of navigating to the remote authorization URL.

Demonstration Video

The following video demonstrates the exploitation chain: sharing the malicious credential with a victim account and triggering the XSS payload.

Root Cause

During the OAuth flow, the browser initiates a top-level navigation to the authorization URL in the oAuthCredentialAuthorize function of the credential service. However, this segment of the program missed sanitation of the Authorization URL.

Screenshot 2026 03 03 at 12.05.56 PM

Fig. 2: Vulnerable source code

Impact: Application Compromise

This is a stored XSS, meaning the payload is saved permanently in the database and served to any user who interacts with the credential. The impact of executing arbitrary JavaScript in the context of an n8n session is significant:

  1. Account Takeover: The attacker can impersonate the victim’s in his session and force actions on their behalf, effectively taking over the account.
  2. Credential Exfiltration: The attacker can then use the XSS to query the internal n8n API and retrieve other credentials stored in the instance.
  3. Instance Control: With admin access gained via the XSS, the attacker can access more credentials, escalate privileges, and gain full control of the n8n instance.

Conclusion

Workflow automation tools like n8n are becoming the backbone of modern IT infrastructure. While they offer immense power and speed, they also centralize trust. A vulnerability in this layer can often be more damaging than a vulnerability in a single isolated application.

We recommend organizations treat their automation platforms as Tier-0 assets, enforce strict access controls, and ensure they are patched promptly.

Timeline

  • Jan 29 : Disclosure of the issue
  • Feb 6 : Issue fixed in v2.6.4

The post N8N: Shared Credentials and Account Takeover appeared first on Blog.

A New Denial-of-Service Vector in React Server Components

React Server Components (RSC) have introduced a hybrid execution model that expands application capabilities while increasing the potential attack surface.

Following earlier disclosures and fixes related to React DoS vulnerabilities, an additional analysis of RSC internals was conducted to assess whether similar denial-of-service risks remained.

This analysis identified a new denial-of-service (DoS) condition that, under specific circumstances, can render a React server unreachable.

Context

Previous reports showed that malformed requests could trigger excessive server-side computation during RSC rendering and serialization. While patches addressed the known attack patterns, it remained unclear whether these issues were isolated or indicative of broader weaknesses.

Technical Overview

The analysis focused on the following RSC code paths:

  • Server Component request parsing
  • Recursive resolution and payload generation

By evaluating server behavior when processing unexpected but syntactically valid inputs, an alternative execution path was identified in which server resources could be exhausted. This behavior is not covered by existing mitigations and could be abused to sustain a denial-of-service condition.

The issue was reported to the React security team. Due to the potential impact, exploitation details are not disclosed here.

Mitigation

While framework-level fixes are under review:

  • Imperva customers are protected against this issue.
  • Imperva’s Application Security solutions detect and block malicious request patterns that trigger abnormal server-side processing before vulnerable paths are reached.

Conclusion

This work highlights the importance of ongoing security evaluation of modern application architectures and the role of layered protections in mitigating denial-of-service conditions.

The post A New Denial-of-Service Vector in React Server Components appeared first on Blog.

❌