Vulnerability GHSA-vr7g-88fq-vhq3
Summary
Paperclip: OS Command Injection via Execution Workspace cleanupCommand
Details
| 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 |
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/shexists natively — commands execute immediately - Windows:
sh.exeis available via Git for Windows (C:\Program Files\Git\bin\sh.exe) — Paperclip requires Git, soshis present on most installations
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.
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
- Desktop user (local_trusted): Any process or malicious web page making local HTTP requests to
127.0.0.1:3100can achieve RCE with zero authentication - Team deployment (authenticated): Any employee with Paperclip access can compromise the server and all repositories managed by it
- Chained attack: Combine with SSRF or DNS rebinding to attack Paperclip instances from the network
Proof of Concept Script
Script
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.exefrom 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
References
Related Vulnerabilities
Other vulnerabilities affecting the same packages