Feb 15, 2026·6 min read·29 visits
Improper handling of the OpenAPI `const` keyword in Orval allowed for code injection during mock generation. Attackers can execute arbitrary code on developer machines by supplying a malicious schema. Fixed in versions 7.20.0 and 8.0.3.
Orval, a popular tool for generating type-safe clients and mocks from OpenAPI specifications, contained a critical code injection vulnerability. By crafting a malicious OpenAPI schema, an attacker could force the generator to inject arbitrary JavaScript into the output files. This means simply importing a spec and running the generator could lead to Remote Code Execution (RCE) on developer machines and CI/CD pipelines.
In the modern web development stack, we love automation. We love tools that take a boring configuration file and spit out thousands of lines of boilerplate code so we don't have to. Orval is one of the heavy hitters in this space, specifically for the React/Vue/Svelte ecosystem. You feed it an OpenAPI specification (Swagger), and it generates type-safe query hooks and, crucially for this story, mock service worker (MSW) handlers.
The premise is simple: If your backend team defines the API structure, your frontend team shouldn't have to manually write mocks for testing. Orval reads the schema and generates TypeScript files containing fake data that matches the types.
But here is the catch: Code generators are effectively compilers. They take input (source) and produce executable output (target). If the compiler is naive about the input, it creates a bridge for an attacker to write directly into your codebase. In CVE-2026-24132, that bridge was the seemingly innocent const keyword in the OpenAPI spec.
The vulnerability lived in packages/mock/src/faker/getters/scalar.ts, inside a function named getMockScalar. This function is responsible for generating a mock value for simple types (strings, numbers, booleans) when the OpenAPI schema defines a specific constant value.
For example, if your schema says a field status must always be "success", Orval wants to generate TypeScript code that sets that property to "success". Ideally, you would do this by serializing the value safely. Orval, however, opted for the "trust me, I'm an engineer" approach of manual string concatenation.
When handling string types, the code effectively did this:
value = `'${item.const}'`;It literally wrapped the input in single quotes and called it a day. For numbers and booleans, it just concatenated them directly. This is the code generation equivalent of SQL injection. The developer assumed item.const would be a benign string like "hello" or "user". They didn't anticipate that item.const might be a snippet of JavaScript designed to break out of that single-quote prison.
Let's look at the smoking gun. This diff shows exactly how the vulnerability was patched. The original code was trying to manually format the output string, which is almost always a security suicide mission when dealing with user-supplied input.
Vulnerable Code (The "Before"):
// packages/mock/src/faker/getters/scalar.ts
if (item.const) {
if (isString) {
// 🚨 DANGER: Direct interpolation
return `'${item.const}'`;
}
// 🚨 DANGER: Direct concatenation for other types
return '' + item.const;
}Fixed Code (The "After"):
// packages/mock/src/faker/getters/scalar.ts
if (item.const) {
// ✅ SAFE: Let JSON.stringify handle escaping
return JSON.stringify(item.const);
}The fix is elegantly simple: JSON.stringify(). This standard function handles quoting, escaping special characters (like newlines or existing quotes), and ensures the output is a valid JavaScript literal. If you pass it a string containing a quote, it escapes it (\"). If you pass it a number, it stays a number. The vulnerability existed solely because the generator tried to reinvent the wheel of serialization.
So, how do we turn a bad string concatenation into Remote Code Execution? We need to provide an OpenAPI specification where a const value breaks the JavaScript syntax of the generated file.
Imagine an attacker convinces a developer to use a malicious openapi.yaml. Maybe it's a pull request to a shared repo, or a compromised remote spec URL.
The Malicious Spec:
openapi: 3.0.0
info:
title: Pwned API
version: 1.0.0
paths: {}
components:
schemas:
TrojanHorse:
type: object
properties:
status:
type: string
# The Injection Payload:
const: "'); require('child_process').execSync('calc'); //"The Generated Code:
When Orval runs, it takes that const string and wraps it in quotes. The resulting TypeScript file looks like this:
export const getTrojanHorseMock = () => ({
// The generated line:
status: ''); require('child_process').execSync('calc'); //'
});Let's break that down:
status: ' starts the string assignment.'); closes the string and the object definition immediately.require('child_process').execSync('calc'); executes the attacker's command (popping a calculator, or stealing SSH keys).//' comments out the trailing quote that Orval added, preventing a syntax error.The next time the developer runs their tests or starts their mock server, the code executes. Game over.
This isn't a vulnerability in the production application; it's a vulnerability in the development lifecycle. This is arguably more dangerous because developer machines often have elevated privileges: SSH keys to production, AWS credentials in ~/.aws/credentials, and write access to the source code repo.
Furthermore, this attack works beautifully in CI/CD pipelines. If your pipeline creates a build environment, pulls the latest specs, generates the client/mocks, and runs tests, the attacker has achieved code execution inside your build agent. They can dump environment variables (secrets) and send them to a remote server before the build even fails.
Because this happens at generation time (or rather, execution-of-generated-code time), standard application firewalls (WAFs) protecting your production API won't save you here. The attack payload enters via a YAML file, not an HTTP request to your app.
The remediation is straightforward: Update Orval. If you are on the v7 branch, move to 7.20.0. If you are living on the edge with v8, update to 8.0.3.
If you cannot update immediately, you must strictly validate the OpenAPI specifications you consume. Do not pull specs from untrusted URLs or allow external contributors to modify the spec file without manual review of the const fields.
For tool authors reading this: Never build code by concatenating strings. Always use an Abstract Syntax Tree (AST) builder (like ts-morph or babel/types) or, at the very least, standard serialization functions like JSON.stringify to generate literals. Code generation is hard; secure code generation is harder.
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
orval orval-labs | <= 7.19.0 | 7.20.0 |
orval orval-labs | >= 8.0.0-rc.0, <= 8.0.2 | 8.0.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-94 (Improper Control of Generation of Code) |
| CVSS v4.0 | 7.7 (High) |
| Attack Vector | Network (Malicious Spec File) |
| Impact | Remote Code Execution (RCE) |
| Affected Component | @orval/mock (getMockScalar) |
| Exploit Status | Proof-of-Concept Available |
The product constructs code using externally-influenced input without properly neutralizing special elements that could modify the syntax or behavior of the generated code.
A Cross-Site Request Forgery (CSRF) vulnerability in the local development server of @tinacms/cli allowed malicious cross-origin pages to send state-changing HTTP requests. This issue permitted attackers to write arbitrary files into a developer's project directory or manipulate search and GraphQL indices without authorization.
A high-severity path traversal vulnerability exists in the @logto/tunnel npm package (part of the Logto repository) prior to version 0.3.9. Remote unauthenticated attackers can exploit this vulnerability to read arbitrary local files by sending crafted HTTP requests with directory traversal sequences when the static file proxy is active.
A critical stored Cross-Site Scripting (XSS) vulnerability was identified in Froxlor server administration software panel before version 2.3.8. Authenticated customers with DNS editor privileges can inject malicious JavaScript into DNS TXT records. Because the application processes these values via a raw formatting callback without context-aware HTML entity encoding, the payload executes in the security context of administrative users who view the affected domain's DNS zones.
An authenticated administrator with privileges to manage admin accounts (such as change_serversettings) can execute arbitrary SQL commands via a second-order SQL injection vulnerability. The flaw resides in Froxlor's administrative API endpoints, specifically during the handling of IP address mapping parameters which are stored as serialized arrays and later interpolated without sanitization into active database queries. This vulnerability allows high-privileged administrative attackers to compromise the database. By injecting a payload into administrative profile metadata, an attacker can extract sensitive credentials, manipulate backend settings, or potentially disrupt database integrity. The vulnerability affects all versions of Froxlor prior to 2.3.8.
CVE-2026-54543 is a DNS Resource Record (RR) Injection vulnerability in Froxlor, an open-source server administration control panel. Prior to version 2.3.8, the DomainZones.add API command failed to perform strict sanitization and validation on the user-controlled record (label) and type parameters before serializing them into BIND-compatible zone files. An authenticated customer with DNS zone management permissions can inject control characters, breaking out of the original record context to define unauthorized resource records within managed zones.
CVE-2026-42533 is a critical security vulnerability discovered in NGINX Open Source, NGINX Plus, NGINX Ingress Controller, and related products, referred to as the 'Two-Pass Capture-Clobbering' bug. The flaw is situated within NGINX's internal evaluation engine when handling complex variables, exposing a heap-based buffer overflow and information leak when a configuration chains regular expression-based map directives with numbered capture groups. An unauthenticated remote attacker can exploit this weakness by transmitting crafted HTTP requests to trigger remote code execution or defeat ASLR.