CVE-2026-25141 — Orval JavaScript Code Injection (Arbitrary JS Execution)
CVE Identifier: CVE-2026-25141
Title: Orval JavaScript Code Injection Vulnerability
Severity: Critical
CVSS Score (V4): 9.3 (Remote, no authentication required, full code execution risk)
Type: Arbitrary JavaScript code injection via unsafe spec field handling
Exploitability: High (remote ability to cause code emission that contains attacker-controlled JS)
Exploit Availability: Public proof-of-concepts exist for educational context only
Official Patch/Upgrade:
🔗 https://github.com/orval-labs/orval/releases/tag/v7.21.0
What This Vulnerability Is
Orval is a tool that takes an API description (OpenAPI/Swagger) and generates JavaScript or TypeScript client code from it. It’s very useful in development pipelines.
The problem with CVE-2026-25141 is that Orval did not completely sanitize certain parts of the API description before putting them into generated code. Specifically, custom fields like x-enum-descriptions were taken from the OpenAPI file and inserted directly into the output without fully escaping dangerous characters.
That means if someone can control or influence an API description — for example in a third-party spec, supplier feed, or a pull request from a contributor — they could make the generator produce code that contains malicious JavaScript.
When developers run or build against that generated code, the injected JS can run in their environment — potentially running commands, exfiltrating secrets, or tampering with build artifacts.
How This Happens
- Orval reads the API spec: It sees fields like descriptions, enum labels, or custom vendor extensions.
- It plugs those values into templates that become TypeScript/JS client files.
- Because the code generator treated these values as safe, characters that normally would be escaped — like comment closers (
*/), backticks, or punctuation-only constructs — ended up in the output unescaped. - By carefully crafting a description, an attacker can break out of a comment or string and insert commands that actually execute when the file runs.
In other words, what was supposed to be plain text becomes executable code.
Why This Is Dangerous
- Build machines and CI servers often run generated code. If malicious code runs there, it can access credentials, deploy artifacts, or move laterally.
- Developers might run this code locally without anticipating danger; they trust a client generator.
- Supply-chain impact: A malicious dependency or tampered API spec can spread this issue silently until code runs.
In practice, this means environments you trust — local machines, CI pipelines, test servers — could be compromised without any obvious breach of your systems.
How It Could Be Exploited
An attacker does not need access to your codebase. What they need is a way to get a crafted API description into your development process. Examples include:
- A pull request that updates API specs.
- A third-party API definition fetched during build time.
- A package update that includes an API spec file.
Once that file is processed by Orval, the malicious content ends up in a JavaScript file. If the generated file is run or transpiled, the injected code will execute in that environment.
Important: Never treat this as a step-by-step exploit guide. This explanation is to help defenders understand where risks lie so they can build prevention and detection.
How to Detect Issues and Indicators of Exploitation
1. Pre-Generation Detection
Look for dangerous patterns in OpenAPI spec files:
- Unescaped comment closers like
*/ - JavaScript punctuation-only sequences (used in obfuscation)
- Fields that are meant to be descriptions but contain code-like text
These are suspicious even if not malicious.
2. Detection After Generation
Generated client code should not contain:
- Raw sequences that break string/comment contexts
- Unexpected executable segments embedded in otherwise descriptive fields
3. CI/CD and Logs
Check build logs for:
- Orval running and producing unexpected warnings
- Generated files triggering unexpected test failures
- Logs showing code execution from generated files
Concrete Detection Rules
These rules focus on spotting suspicious patterns relevant to this vulnerability. They are not attack payloads; they are defensive patterns.
Sigma Rule
title: Suspicious OpenAPI Spec Field with Potential JS Injection
id: orval-js-injection-detection
description: Detects patterns in OpenAPI specification files that may indicate attempts to inject JavaScript into generated clients.
status: experimental
level: high
references:
- https://github.com/orval-labs/orval/releases/tag/v7.21.0
logsource:
product: generic
service: file-monitoring
detection:
selection:
EventType: "FileWrite"
FileName|endswith: [".yaml", ".yml", ".json"]
Content:
- "*x-enum-descriptions*/*/"
- "*x-enum-descriptions*`*`*"
condition: selection
fields:
- FileName
- Content
falsepositives:
- Legitimate OpenAPI specs that use nonstandard punctuation in descriptions
level: high
What this does:
It watches for file writes where the OpenAPI file itself contains patterns like an unescaped comment closer (*/) in description fields. That’s a key symptom of unsafe input.
Splunk/SIEM Query
index=your_index sourcetype="fs_events" (file_extension="json" OR file_extension="yaml" OR file_extension="yml")
| search EventType="FileWrite" AND (
match(_raw, "x-enum-descriptions.*\\*/") OR
match(_raw, "x-enum-descriptions.*`.*`")
)
| table _time, host, user, path, _raw
| rename path as "File Path"
What this does:
This looks at filesystem event logs and flags writes to API specification files that include patterns that shouldn’t normally be there unless someone is attempting to sneak executable content into a spec.
GitHub Actions: Lint OpenAPI Specs Before Generation
Here is a ready-to-use GitHub Actions workflow that will scan any OpenAPI file in your repository for unsafe patterns before running Orval. If it finds them, the build fails with a clear error.
name: Lint OpenAPI Specs
on:
pull_request:
paths:
- "**/*.yaml"
- "**/*.yml"
- "**/*.json"
jobs:
lint-openapi:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v4
- name: Scan for unsafe patterns
id: scan
run: |
# Regex patterns that indicate comment breakers or strange code characters
bad_patterns='(\*\/|`.*`|[][!+]+)'
found=0
for file in $(find . -type f -name "*.yaml" -o -name "*.yml" -o -name "*.json"); do
if grep -E "$bad_patterns" "$file"; then
echo "Unsafe pattern found in $file"
found=1
fi
done
if [ $found -ne 0 ]; then
echo "Error: Unsafe tokens detected in OpenAPI specs."
exit 1
fi
- name: Continue if clean
run: echo "Specs appear clean; proceeding with generation"
How it works:
- Every PR that touches spec files triggers this job.
- It scans for comment closers (
*/), backticks, and punctuation-heavy sequences. - If any unsafe pattern is found, the job fails early before code generation.
Practical Defensive Steps
- Upgrade Orval immediately to the patched version linked above. Regenerate all client code.
- Treat OpenAPI specs like code. Lint them; review them manually or automatically before using them to generate code.
- Add the GitHub Actions job above to your repo — this blocks unsafe specs early.
- Scan your artifact feeds (package registries, internal APIs) for specs with suspicious tokens.
- Monitor build logs for any unexpected execution in code generated from specs.
Final Takeaways
- This vulnerability wasn’t a bug in JavaScript itself — it was in the way text was put into generated code without escaping it properly. That’s a classic code injection scenario, and it’s exactly why we treat input as unsafe by default.
- The real risk is not just that someone can write “bad text,” but that build systems and developers often trust generated code. With a few punctuation characters in the wrong place, code that looked safe can suddenly do harmful things.
- The workflows and detection rules above do not stop every possible attack, but they greatly reduce the chance that unsafe API specs ever reach code generation.
- Always combine automated scanning with human review when dealing with anything that influences code generation.
