GHSA-653q-5476-x79g: Code Injection

Published Sep 3, 2026
·
Updated

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

1 affected componentFixes available
npm/orval<8.21.0
8.21.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/orval to a version that resolves this vulnerability.

    Fixed in 8.21.0
  2. Upgrade

    Upgrade orval to a version that resolves this vulnerability.

    Fixed in 8.19.0
  3. 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)
  4. 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

Sep 3, 2026
Advisory Published
via GitHub·06:18 PM
Data Sourced
via GitHub·06:18 PM
DescriptionWeaknessAffected Software

Frequently Asked Questions

1

Which generated clients are affected?

The issue affects orval's zod client and the hono client, which reuses the zod generation path.

2

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.

3

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.

4

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.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203