Skip to content

Phaze is secure by design

React is insecure by design — not for lack of care, but because React Server Components are defined by a server/client boundary: components and function arguments are serialized on one side and deserialized on the other, and deserializing untrusted, attacker-controllable input on the far side has produced a steady stream of critical CVEs since December 2025 (the catalogue below). They aren’t isolated mistakes — they’re the wire.

Phaze is secure by design for the mirror reason: it is isomorphic — there is no server/client boundary to serialize across, so the deserialization sink and the bypassable gate have nowhere to exist. This page is the case, item by item.

CVEClassRoot causeScope / status
CVE-2025-55182 (“React2Shell”)Unauthenticated RCE, CVSS 10.0Server-side prototype pollution in the RSC deserializer → arbitrary code via child_processReact 19.0–19.2 / Next 13.3–14.x. On CISA’s Known-Exploited list — in the wild. Patched React 19.0.1/19.1.2/19.2.1, Next 14.2.35
CVE-2025-29927Authorization bypassx-middleware-subrequest header (an internal loop-guard) skips middleware entirely → reach protected routes + _next/dataPatched 12.3.5 / 13.5.9 / 14.2.25 / 15.2.3
Source-code exposureInformation disclosureMalformed Server Function args cause the function to return its own source when arguments are stringifiedDisclosed alongside the Dec 2025 DoS
CVE-2026-23864 → -23869 → -23870 (the chain)Denial of serviceCyclic / pathological deserialization → CPU exhaustion, OOM, process killRSC 19.x / all Next App Router 13.x–16.x. Each fix incomplete — a new vector surfaced against the previously-patched versions

The fourth row is the tell. The December DoS fix was incomplete; CVE-2026-23864 (Jan 2026), -23869 (May 2026), and -23870 (immediately after, against those same “fixed” versions) are the same sink re-found. A security write-up titles it plainly: “DoS Vulnerability That Keeps Coming Back on React Server Components.” You don’t get a recurring sink from a one-off bug — you get it from an architecture.

Two structural surfaces — both born of the server/client split

Section titled “Two structural surfaces — both born of the server/client split”
  1. The serialization boundary. RSC must serialize across server↔client; the deserialize step ingests untrusted input. That is the RCE / DoS / source-exposure sink — and it recurs because it is the wire, not a defect on top of it.
  2. The detachable gate. Authorization placed in a middleware layer in front of the route is, by definition, a layer that can be skipped (CVE-2025-29927). Next’s own post-incident guidance now says it outright: “middleware should supplement, not replace, robust security measures placed closer to the data source.” That is an admission that the gate-in-front model was the wrong place.

How Phaze removes the surface — isomorphism + declarative mechanics

Section titled “How Phaze removes the surface — isomorphism + declarative mechanics”

Every item above lives on the server/client split. Phaze is isomorphic — there is no split — so there is nothing to serialize across, nothing to deserialize, and no separable gate to skip.

React surfacePhaze structural answer
RSC serialize / deserialize wire (the RCE + DoS sink)No serialization protocol. One universal component runs on both sides — its code ships and runs, it is never serialized into a Flight payload. Data crosses as plain JSON (SSR-seeded, read as a value, never reconstructed) or via a transport action whose first act is input.parse (zod). No object-graph reconstruction → the prototype-pollution / cyclic-deserialization sink has nowhere to live.
Closure-captured server data serialized to the clientNone. newAction compiles to a bare object literal + an inline fetch arrow — no closure is serialized to the browser, so there is no captured data to leak.
Server Function returns its own source on malformed inputNo such path. Handlers are server-only code; the client holds a typed fetch, never a serialized function that can reflect its source.
Middleware auth bypass (skip the layer, reach the route)No detachable gate. The restricted guard is a server-only page export run inside the route’s own dispatch (core()) — isomorphism puts server-only logic on the universal page, not in a layer in front of it. There is no hop to skip, and it is “close to the data” — Next’s own remediation, by construction.

Redirects are an attack surface too — so the gate signs them

Section titled “Redirects are an attack surface too — so the gate signs them”

Auth gates classically lean on redirects (302 → /login), and a redirect is an instruction the browser obeys: when its target derives from input (/login?next=…) it’s the textbook open redirect, and even a fixed target can be swapped by a MITM or a poisoned cache. Phaze treats the redirect as surface and shrinks it two ways:

  1. Most outcomes don’t redirect at all. 403 / 404 / 500 render in place at the attempted URL with the real status code — reserved status-code pages (403.phaze / 404.phaze / 500.phaze) emitted by the in-core() guard. No Location header, no navigation, nothing to tamper with.

  2. The one flow-redirect (401 → login) is Ed25519-signed, and the browser verifies it for free. The server signs the redirect’s to return-path (with an exp window) using PHAZE_SIGN_KEY; the phaze-router verifies that signature with the public key before following — and because Ed25519 verify is WebCrypto-native, the check costs 0 bytes on the client (the same property behind signed transport). So a redirect the browser honors is provably server-issued; a forged/tampered Location — a swapped to=https://evil.com, a MITM, a poisoned cache — is rejected before location.href. The return-path can’t be altered without invalidating the signature, and exp bounds replay of a stale link.

SurfaceReact / NextPhaze
Deserialization RCE (prototype pollution)CVE-2025-55182, 10.0, exploitedabsent — wire is data, input.parse’d, never reconstructed
Deserialization DoSrecurring chain — CVE-2026-23864 / -23869 / -23870absent — same reason
Source-code exposuremalformed args reflect sourceabsent — handlers are server-only, no serialized function
Closure data leak to clientserialized closuresabsent — no closure serialization
Auth gate bypassCVE-2025-29927 (skippable middleware)absent — restricted guard in core(), no separable layer
Auth-redirect tampering / open redirectunsigned 302, ?next= reflection (known footgun)Ed25519-signed, browser-verified before follow — or isomorphicAuth (no redirect)
Where the risk comes fromthe server/client serialization boundarythere is no boundary (isomorphic)
  • Hardened Transport — the field-by-field contrast and the cryptographic additions (sign: / verify: / encrypt:).
  • Phaze Transport — the typed, schema-validated wire that replaces the RSC protocol.
  • Router — isomorphism, SSR-seeding, and the per-route restricted guard.