Skip to content

CVE-2026-37281: Verified Repro With Script Download

CVE-2026-37281: zenshin: OS command injection in /stream-to-vlc url query parameter

CVE-2026-37281 is verified against the affected target. Vulnerability class: RCE. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00140.

REPRO-2026-00140 RCE May 22, 2026 CVE entry ↗ .txt
Severity
CRITICAL
CVSS
9.8
Reproduced in
28m 3s
Tool calls
190
Spend
$1.37
01 · Overview

What Is CVE-2026-37281?

CVE-2026-37281 is a critical OS command injection vulnerability in zenshin, an Electron application, where the Express backend's /stream-to-vlc route passes an unsanitized url query parameter into a shell command, letting any unauthenticated actor who can reach the backend port execute arbitrary commands. Pruva reproduced it (reproduction REPRO-2026-00140).

02 · Severity & CVSS

CVE-2026-37281 Severity & CVSS Score

CVE-2026-37281 is rated critical severity, with a CVSS base score of 9.8 out of 10.

CRITICAL threat level
9.8 / 10 CVSS base
Weakness CWE-78 (OS Command Injection) — Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')

Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.

How to Reproduce CVE-2026-37281

$ pruva-verify REPRO-2026-00140
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00140/artifacts/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-37281

Reproduced by Pruva's autonomous agents — 190 tool calls over 28 min. Full root-cause analysis and the complete transcript are below.

How the agent worked 629 events · 190 tool calls · 28 min
28 minDuration
190Tool calls
145Reasoning steps
629Events
Agent activity over 28 min
Support
16
Repro
326
Variant
283
0:0028:03

Root Cause and Exploit Chain for CVE-2026-37281

Summary

zenshin is an Electron application with an embedded Express HTTP backend. The backend route GET /stream-to-vlc takes a url query parameter and interpolates it unsanitized into a shell command executed via child_process.exec. A crafted url value containing shell metacharacters (e.g., a closing quote followed by a command separator) allows arbitrary command execution on the host, resulting in unauthenticated remote code execution for any actor that can reach the backend port.

Impact

  • Package/component affected: zenshin (Electron/Express backend)
  • Affected versions: < 2.7.0
  • Fixed version: 2.7.0 (commit 7d31c6edfbac978f0ad44c66d761bab9dcd2fa27)
  • Risk level: Critical — CVSS 3.1 base 9.8
  • Consequences: Unauthenticated attackers on the local network (or any host that can reach the Express port) can execute arbitrary OS commands as the user running zenshin.

Root Cause

In the vulnerable commit (7d31c6edfbac978f0ad44c66d761bab9dcd2fa27~1), the /stream-to-vlc route in Electron/zenshin-electron/src/main/index.js constructs a shell command by directly interpolating the user-supplied url query parameter:

const vlcPath = '"C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe"'
const vlcCommand = `${vlcPath} "${url}"`
exec(vlcCommand, (error) => { ... })

Because exec invokes /bin/sh -c (or cmd.exe /c on Windows), any shell metacharacters in url are interpreted by the shell. An attacker can break out of the double-quote wrapper with a payload such as x"; touch /tmp/pwned; echo "x, causing the shell to execute the injected touch /tmp/pwned command after the (non-existent) VLC executable fails.

The fix commit (7d31c6edfbac978f0ad44c66d761bab9dcd2fa27) completely removes the /stream-to-vlc Express endpoint and replaces the ipcMain handler with spawn, passing the player path and URL as separate array arguments with shell: false, which prevents shell interpretation entirely.

Reproduction Steps

The reproduction script is repro/reproduction_steps.sh. It performs the following steps:

  1. Checks out the vulnerable commit (7d31c6edfbac978f0ad44c66d761bab9dcd2fa27~1).
  2. Installs dependencies and builds the project with npm run build inside Electron/zenshin-electron.
  3. Runs the actual built out/main/index.js with a Node.js mock harness that stubs electron, @electron-toolkit/utils, and electron-deeplink, allowing the Express backend to start without a real Electron runtime.
  4. Sends a crafted GET /stream-to-vlc?url=... request with the payload x"; touch /tmp/pwned; echo "x.
  5. Verifies that /tmp/pwned is created, proving arbitrary command execution.
  6. Repeats steps 1–5 with the fixed commit (7d31c6edfbac978f0ad44c66d761bab9dcd2fa27).
  7. Verifies that the endpoint returns 404 Cannot GET /stream-to-vlc and /tmp/pwned is NOT created.

Evidence

  • Vulnerable commit result: statusCode=200, responseBody="VLC launched successfully", pwned_exists=true
  • Fixed commit result: statusCode=404, responseBody="Cannot GET /stream-to-vlc", pwned_exists=false
  • Log files:
    • logs/vulnerable.json — HTTP response and sentinel file state for the vulnerable build
    • logs/fixed.json — HTTP response and sentinel file state for the fixed build
    • logs/run.log — full build and execution logs
  • Runtime manifest: repro/runtime_manifest.json captures the structured verdict.

Recommendations / Next Steps

  • Fix approach: Remove or replace exec with spawn using an array of arguments and shell: false, as the upstream fix does. This prevents the shell from parsing user input.
  • Input validation: If the endpoint must be retained, strictly validate the url parameter against an allow-list of safe stream URL patterns before passing it to any process launcher.
  • Network binding: Bind the Express backend to 127.0.0.1 only (also done in the fix) to reduce the attack surface.
  • Testing: Add integration tests that attempt shell injection against /stream-to-vlc and similar endpoints to prevent regressions.

Additional Notes

  • Idempotency: The reproduction script was run twice consecutively with identical results on both runs.
  • Edge cases / limitations: The reproduction uses a mock Electron environment because a real Electron GUI cannot run in a headless CI/container environment. The mock stubs only Electron-specific APIs (window creation, IPC, deeplinks); the Express backend and the vulnerable route handler are the actual transpiled code from the project build.

CVE-2026-37281 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:000:38
0:00
session startedaccounts/fireworks/models/kimi-k2p6 · cve-2026-37281 · cve-2026
0:02
0:03
web search
0:06
0:06
0:29
0:29
extract_facts
no facts extracted
0:30
0:30
0:30
supportrepro
0:33
0:34
0:34
0:34
0:35
0:35
0:35
0:36
0:36
0:37
0:38
$git clone --depth=100 https://github.com/hitarth-gg/zenshin.git external/zenshin
0.6s
Cloning into 'external/zenshin'...

Artifacts and Evidence for CVE-2026-37281

Scripts, logs, diffs, and output captured during the reproduction.

No artifacts available

08 · How to Fix

How to Fix CVE-2026-37281

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-37281 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-37281

How does the CVE-2026-37281 command injection attack work?

An attacker sends a GET request to /stream-to-vlc with a url value that breaks out of the double-quote wrapper (e.g. a payload like x"; touch /tmp/pwned;), so the shell treats the remainder as a separate command that executes with the privileges of the user running zenshin -- no authentication required.

How severe is CVE-2026-37281?

Critical -- unauthenticated attackers on the local network, or any host able to reach the Express backend port, can execute arbitrary OS commands as the user running zenshin.

How can I reproduce CVE-2026-37281?

Download the verified script from this page and run it in an isolated environment against zenshin before 2.7.0 (fixed in 2.7.0). It sends a crafted url query parameter containing shell metacharacters to the /stream-to-vlc endpoint and confirms the injected command executes on the host.
11 · References

References for CVE-2026-37281

Authoritative sources for CVE-2026-37281 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.