GHSA-653q-5476-x79g: Code Injection
Summary
orval's zod client emits each query parameter name as a double-quoted key in the generated zod.object({...}) request-validation schema WITHOUT escaping the double quote. A " in the query parameter name closes the key and lands in object-literal context, where an injected computed property key [expr] is evaluated when zod.object({...}) runs -- at MODULE IMPORT (export const OpQueryParams = zod.object({...}) executes on load) -> import-time RCE. The query parameter name is a pure data field. Verified on orval 8.19.0 / Node.
Details
export const OpQueryParams = zod.object({ "a":zod.string(),[require("fs").writeFileSync("PWNED","")]:zod.string(),"b": ... })
Also affects the hono client (reuses zod generation). orval escapes values in zod arrays but not keys in zod.object. Sibling fields: schema property name, header parameter name (CVE-97) (separate reports). Distinct from orval's $ref / route-path / server-url / zod-default findings.
PoC
reproduce.sh (+ makespec.py) attached: a query parameter name that breaks the zod.object key and injects a computed key; evaluating it (= importing the module) writes the marker. Verified on 8.19.0.
Impact
JavaScript / OS command execution at import time for anyone who generates an orval zod client from an attacker-controlled spec and imports it.
Suggested fix
Escape the query parameter name for the JS string key (JSON.stringify) in the zod.object key generation; never interpolate a raw name adjacent to [ ] in object-literal position. maintainer-report.txt makespec.py reproduce.sh
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
npm/orvalto a version that resolves this vulnerability.Fixed in 8.21.0 - Upgrade
Upgrade
orvalto a version that resolves this vulnerability.Fixed in 8.19.0 - Configuration
When generating the zod.object({...}) schema for query parameters, escape the query parameter name used as the JS string key (e.g., use JSON.stringify for the key) so that a parameter name cannot break out of the quoted key and inject a computed property key that is evaluated at module import time.
orval-generated Zod schema (zod.object key generation) escape query parameter name when generating zod.object({...}) keys = JSON.stringify(queryParamName) as the JS object key (never interpolate raw name adjacent to [ in object-literal position) - Compensating control
For any attacker-controlled OpenAPI/orval spec, do not generate/compile/import the resulting orval Zod client in a process that has access to sensitive filesystem/credentials; treat the import-time code generation as untrusted execution.
Event History
Frequently Asked Questions
Which generated clients are affected?
The issue affects orval's zod client and the hono client, which reuses the zod generation path.
What must an attacker control to trigger the issue?
An attacker needs to supply an API specification containing a query parameter name with a double quote and injected JavaScript in the resulting object-literal context. The query parameter name is treated as data but is emitted without escaping.
When does the injected code run?
The generated code executes when the generated module is imported. The injected computed property key is evaluated as zod.object({...}) runs during module load.
How can I check generated output for exposure?
Inspect generated zod request-validation schemas for query parameter names containing double quotes or unexpected computed property keys such as [expression] inside zod.object({...}). A malicious specification can cause generated code to contain executable expressions rather than only quoted property names.