Skip to main content
Vulnerability Database/CVE-2026-103918

CVE-2026-103918: oRPC Prototype Pollution RCE Vulnerability

CVE-2026-103918 is a prototype pollution vulnerability in oRPC that enables remote code execution through __proto__ manipulation in ZodSmartCoercionPlugin. This post explains the technical details, affected versions, and mitigation steps.

Published:

CVE-2026-103918 Overview

oRPC is a TypeScript framework for building end-to-end type-safe APIs that comply with OpenAPI standards. A prototype pollution vulnerability [CWE-915] affects the @orpc/zod package in versions prior to 1.14.10. The ZodSmartCoercionPlugin and experimental_ZodSmartCoercionPlugin collect object and record properties into plain objects and resolve shape keys through the prototype chain. A remote client reaching a procedure with an object or record input can supply __proto__ to replace the prototype of the returned request object. Attacker-controlled inherited values then reach application lookups during request processing.

Critical Impact

Remote unauthenticated attackers can inject properties into per-request objects through the prototype chain, influencing downstream application lookups and triggering unhandled TypeError exceptions during Zod validation.

Affected Products

  • @orpc/zod package versions prior to 1.14.10
  • Applications using ZodSmartCoercionPlugin
  • Applications using experimental_ZodSmartCoercionPlugin

Discovery Timeline

  • 2026-10-02 - CVE-2026-103918 published to NVD
  • 2026-10-06 - Last updated in NVD database

Technical Details for CVE-2026-103918

Vulnerability Analysis

The flaw lives in the smart coercion logic within packages/zod/src/coercer.ts and packages/zod/src/zod4/coercer.ts. The coercer builds request representations using plain JavaScript objects, which inherit from Object.prototype. When processing incoming request payloads, the plugin reads shape keys through standard property access, allowing lookups to traverse the prototype chain.

For record schemas, submitting a __proto__ key replaces the prototype of the per-request object. This allows an attacker to set inherited properties that later reach application code performing property reads on the parsed object. For object schemas, specifying keys such as constructor, toString, or __proto__ causes the coercer to resolve inherited members as Zod schemas, producing an unhandled TypeError before validation completes.

The advisory confirms the issue does not modify the global Object.prototype, unrelated objects, other requests, or other users. The availability impact is scoped to the crafted request rather than persistent process-wide state.

Root Cause

The root cause is improperly controlled modification of object prototype attributes [CWE-915]. The coercer used plain {} objects whose prototype chain remained writable through __proto__, and resolved shape keys with prototype-chain lookups rather than own-property checks.

Attack Vector

Any remote client able to invoke a procedure accepting an object or record input can send a JSON payload containing a __proto__ key. No authentication or user interaction is required when the procedure is publicly reachable. The malicious key reshapes the parsed request object, after which application code reading unexpected properties receives attacker-controlled values.

typescript
// Patch excerpt - packages/zod/src/coercer.ts
   ZodTypeAny,
   ZodUnion,
 } from 'zod/v3'
-import { guard, isObject } from '@orpc/shared'
+import { guard, isObject, NullProtoObj } from '@orpc/shared'
 import { ZodFirstPartyTypeKind } from 'zod/v3'
 import { getCustomZodDef } from './schemas/base'

// Patch excerpt - packages/zod/src/zod4/coercer.ts
   $ZodType,
   $ZodUnion,
 } from 'zod/v4/core'
-import { guard, isObject } from '@orpc/shared'
+import { guard, isObject, NullProtoObj } from '@orpc/shared'

Source: GitHub Commit 26314df. The fix replaces plain object construction with NullProtoObj, a null-prototype object that cannot be polluted through __proto__.

Stop Remote Code Execution Before It Runs

Singularity™ Endpoint detects and blocks exploit attempts at machine speed, including zero-days and novel attack techniques.

Stop Exploit Attempts

Detection Methods for CVE-2026-103918

Indicators of Compromise

  • HTTP request bodies to oRPC procedures containing a __proto__ key in JSON payloads
  • HTTP request bodies containing suspicious keys such as constructor, prototype, or toString targeting object or record inputs
  • Unhandled TypeError exceptions originating from @orpc/zod coercer code paths in application logs
  • Spikes in 500-level responses correlated with payloads directed at oRPC endpoints

Detection Strategies

  • Inspect inbound JSON payloads at the application gateway or WAF for reserved property names in object positions and alert on matches to oRPC routes.
  • Correlate server-side exceptions referencing @orpc/zod coercer frames with the request bodies that produced them to identify exploitation attempts.
  • Run a software composition analysis scan against package-lock.json and pnpm-lock.yaml to flag any @orpc/zod version below 1.14.10.

Monitoring Recommendations

  • Enable structured logging of request paths and exception stack traces for all oRPC procedures to support retroactive hunting.
  • Monitor error rate dashboards for oRPC endpoints and alert on sustained increases in TypeError occurrences before validation.
  • Add continuous dependency monitoring to detect downgrade or reintroduction of vulnerable @orpc/zod releases in future builds.

How to Mitigate CVE-2026-103918

Immediate Actions Required

  • Upgrade @orpc/zod to version 1.14.10 or later across all services that expose procedures over HTTP.
  • Audit every procedure definition that accepts object or record schemas and inventory callers that are reachable without authentication.
  • Review application code paths that read dynamic properties from parsed request objects for safe property access patterns.

Patch Information

The fix is published in oRPC version 1.14.10. The patch introduces NullProtoObj from @orpc/shared and replaces plain object construction in both the Zod v3 and Zod v4 coercers so request objects no longer inherit from Object.prototype. See the GitHub Security Advisory GHSA-gcgf-fh7c-8gf2, Pull Request #1727, and the v1.14.10 release notes.

Workarounds

  • Deploy a WAF or proxy rule that rejects JSON request bodies containing __proto__, constructor, or prototype as object keys for affected routes.
  • Replace use of ZodSmartCoercionPlugin and experimental_ZodSmartCoercionPlugin with stricter schemas that do not rely on smart coercion until the upgrade can be deployed.
  • Access request properties using Object.hasOwn() or Reflect.has() with own-property checks instead of relying on prototype-chain lookups.
bash
# Upgrade the vulnerable package
npm install @orpc/zod@1.14.10

# Verify installed version
npm ls @orpc/zod

# Audit the lockfile for lingering vulnerable copies
npm audit --production

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.