# GHSA-3pw3-v88x-xj24: Paperclip: Arbitrary File Read via Agent-Controlled adapterConfig.instructionsFilePath

> An attacker with an Agent API key can read arbitrary files from the server host filesystem by manipulating agent configuration paths.

- **Severity:** Not scored
- **Exploited in the wild:** Not known
- **Login needed:** Any signed-in user
- **Attackable:** Over the internet
- **Victim action needed:** Not needed
- **Fix available:** Yes
- **Published:** 16 Apr 2026

## What is GHSA-3pw3-v88x-xj24?

GHSA-3pw3-v88x-xj24 is a path traversal vulnerability in @paperclipai/shared, published on 16 Apr 2026. Any signed-in user can exploit it over the network, with no action from the victim.

### Official description

### Summary
Paperclip contains an arbitrary file read vulnerability that allows an attacker with an Agent API key to read files from the Paperclip server host filesystem.
The vulnerability occurs because agents are allowed to modify their own adapterConfig through the /agents/:id API endpoint.
The configuration field adapterConfig.instructionsFilePath is later read directly by the server runtime using fs.readFile().
Because no validation or path restriction is applied, an attacker can supply an arbitrary filesystem path.
The Paperclip server then attempts to read that path from the host filesystem during agent execution.
This breaks the intended trust boundary between agent runtime configuration and server host filesystem access, allowing a compromised or malicious agent to access sensitive files on the host system.

### Details
#### Root Cause
No path normalization, allowlist, or workspace boundary validation is applied before the filesystem read occurs.
Agent configuration can be modified through the API endpoint:
```
PATCH /api/agents/:id
```
The validation schema allows arbitrary configuration fields inside adapterConfig.
File:
```
packages/shared/src/validators/agent.ts
```
Schema fragment:
```
adapterConfig: z.record(z.unknown())
```
Because of this schema, attackers can inject arbitrary configuration values, including:
```
adapterConfig.instructionsFilePath
```
During agent execution, the server runtime reads this path directly from the host filesystem using fs.readFile().
Relevant code path:
```
packages/adapters/claude-local/src/server/execute.ts
```
Execution flow:
```
adapterConfig.instructionsFilePath
        ↓
execute()
        ↓
fs.readFile(instructionsFilePath)
        ↓
file content loaded into runtime
```
Vulnerable logic:
```
const instructionsContent = await fs.readFile(instructionsFilePath, "utf-8");
```
Because the value originates from attacker-controlled configuration and no validation or sandboxing is applied, this becomes a direct host filesystem read primitive.

#### Affected Files
Primary vulnerable file:
```
packages/adapters/claude-local/src/server/execute.ts
```
Relevant function:
```
execute()
```
Sensitive operation:
```
fs.readFile(instructionsFilePath)
```
Configuration source:
```
PATCH /api/agents/:id
```
Validation logic:
```
packages/shared/src/validators/agent.ts
```

#### Attacker Model
Required privileges
Attacker requires:
```
Agent API key
```
Agent credentials are intended for automation and integration with external runtimes.
These credentials are commonly used by:
```
agent runtime environments
third-party integrations
automation pipelines
```
Agent credentials are not intended to grant direct access to the server host filesystem.
No board or administrator privileges are required.

#### Attacker Chain
Complete exploit chain:
```
Attacker obtains Agent API key
        ↓
PATCH /api/agents/:id
        ↓
Inject adapterConfig.instructionsFilePath
        ↓
POST /api/agents/:id/wakeup
        ↓
Server executes agent run
        ↓
execute.ts
        ↓
fs.readFile(attacker_path)
        ↓
Server reads host filesystem path
```
This allows an attacker to read arbitrary files accessible to the Paperclip server process.

#### Trust Boundary Violation
Paperclip’s architecture assumes the following separation:
```
Agent runtime
        ↓
Paperclip orchestration layer
        ↓
Server host filesystem

Agents should only interact with repositories and workflows through the orchestration layer.

However, because agent-controlled configuration is passed directly into fs.readFile, the boundary collapses:

Agent configuration
        ↓
Server filesystem access
```
This allows an agent to access files outside its intended permission scope.

#### Why This Is a Vulnerability (Not Expected Behavior)
The instructionsFilePath configuration appears intended for trusted operators configuring agent runtime behavior.
However, the current API design allows agents themselves to modify this configuration through the agent API.
Because agent credentials may be exposed to external systems or runtime environments, allowing them to control server filesystem paths introduces a security vulnerability.
Therefore:
```
Operator-controlled configuration → expected feature
Agent-controlled configuration → arbitrary file read vulnerability
```
The issue arises from insufficient separation between configuration authority and filesystem access authority.

### PoC
The following PoC demonstrates that the server attempts to read an attacker-controlled filesystem path.
To avoid accessing sensitive data, the PoC uses a non-existent path.
#### Step 1 — Setup Environment
Run server:
```
$env:SHELL = "C:\Program Files\Git\bin\sh.exe"
npx paperclipai onboard --yes
```
Login Claude:
```
claude
/login
```
#### Step 2 — Obtain Agent API key
Create an agent via the UI or CLI and obtain its API key.
Example:
<img width="1475" height="710" alt="image" src="https://github.com/user-attachments/assets/fcc0dfe9-1271-4eed-af0a-7dd83dfa9ad4" />

#### Step 3 — Identify agent ID
```
GET /api/agents/me
```
<img width="824" height="196" alt="image" src="https://github.com/user-attachments/assets/af4a16bb-9bff-485d-af23-4a85d31486fc" />

#### Step 4 — Inject malicious configuration
```
PATCH /api/agents/{agentId}
```
Payload example:
```powershell
{
  "adapterConfig": {
    "instructionsFilePath": "C:\\definitely-does-not-exist-paperclip-poc.txt"
  }
}
```
Example PowerShell payload:
```powershell
$patchBody = @{
  adapterConfig = @{
    instructionsFilePath = "C:\definitely-does-not-exist-paperclip-poc.txt"
  }
} | ConvertTo-Json -Depth 10
```
<img width="1891" height="963" alt="image" src="https://github.com/user-attachments/assets/1a8c41b4-c053-4498-8bf5-ce41c7dfa1b5" />

Step 5 — Trigger execution
```
POST /api/agents/{agentId}/wakeup
```
<img width="927" height="376" alt="image" src="https://github.com/user-attachments/assets/d6107b64-1b5e-493c-9a66-45a4713260b5" />

#### Step 6 — Observe server log
Server log shows:
```
ENOENT: no such file or directory, open 'C:\definitely-does-not-exist-paperclip-poc.txt'
    at async Object.readFile
    at async Object.execute (.../adapter-claude-local/dist/server/execute.js)
```
This confirms the server attempted to read an attacker-controlled filesystem path.
<img width="1916" height="166" alt="image" src="https://github.com/user-attachments/assets/2470438a-bf5a-4f6f-848c-b134d3f0cc3f" />

### Impact
Successful exploitation allows attackers to read sensitive files accessible to the Paperclip server process.
Examples of potentially exposed data include:
```
environment configuration (.env)
SSH private keys
database credentials
API tokens
CI secrets
```
Possible attacker actions:
```
exfiltrate secrets
access private repositories
steal infrastructure credentials
pivot into connected services
```
Because Paperclip orchestrates repositories, agents, and automation tasks, disclosure of such secrets may lead to compromise of the broader deployment environment.

### Recommended Fix
#### Restrict configuration authority
Agents should not be allowed to modify filesystem-sensitive configuration fields.
Example mitigation:
```
adapterConfig.instructionsFilePath
```
should only be configurable by board/admin actors.

#### Path validation
Restrict file access to a safe directory such as:
```
workspace/
agent-config/
```
Reject:
```
absolute paths
system directories
paths containing ".."
```

#### Avoid direct filesystem reads from configuration
Instead of:
```
fs.readFile(user_supplied_path)
```
use:
```
readFile(workspaceSafePath)
```
Example guard
```ts
if (
  request.auth?.principal === "agent" &&
  body?.adapterConfig?.instructionsFilePath
) {
  throw new Error(
    "Agents are not permitted to configure instructionsFilePath"
  );
}
```

### Security Impact Statement
An authenticated attacker with an Agent API key can modify their agent configuration to inject an arbitrary filesystem path into adapterConfig.instructionsFilePath.
The Paperc

## Which versions are affected by GHSA-3pw3-v88x-xj24?

2 open source packages ship an affected version, including @paperclipai/shared.


| Package | Ecosystem | Affected | Fixed in |
| --- | --- | --- | --- |
| `@paperclipai/shared` | npm | All versions | 2026.416.0 |
| `@paperclipai/shared` | npm | All versions | 2026.416.0 |

## How do I fix GHSA-3pw3-v88x-xj24?

Upgrade @paperclipai/shared to 2026.416.0 or later.

## Is GHSA-3pw3-v88x-xj24 being exploited?

There is no known exploitation of GHSA-3pw3-v88x-xj24 in the wild and no public exploit code.

## Fix prompt for AI coding agents

```text
Check this codebase for GHSA-3pw3-v88x-xj24 and fix it if it is affected.

What it is: GHSA-3pw3-v88x-xj24 is a path traversal vulnerability in @paperclipai/shared, published on 16 Apr 2026. Any signed-in user can exploit it over the network, with no action from the victim.
Exploitation: There is no known exploitation of GHSA-3pw3-v88x-xj24 in the wild and no public exploit code.

Affected packages and fixed versions:
- @paperclipai/shared (npm): affected all versions; fixed in 2026.416.0
- @paperclipai/shared (npm): affected all versions; fixed in 2026.416.0

Task:
1. Search the dependency manifests and lockfiles (for example package.json, package-lock.json, requirements.txt, poetry.lock, uv.lock, pom.xml, build.gradle, go.mod, Cargo.lock, Gemfile.lock) and any Dockerfiles for the affected packages, including transitive dependencies.
2. If an affected version is in use, upgrade it to the fixed version for its release line with the project's package manager, so the lockfile is regenerated. Prefer the smallest upgrade that fixes it.
3. If there is no fix, or the upgrade would break the build, do not guess: explain the risk and the safest workaround instead.
4. Run the tests and summarise what changed and why.
5. If nothing in the project is affected, say so and change nothing.

Reference: https://insights.sbomify.com/GHSA-3pw3-v88x-xj24/ (Markdown: https://insights.sbomify.com/GHSA-3pw3-v88x-xj24/index.md)
```

## Sources

- OSV: https://osv.dev/vulnerability/GHSA-3pw3-v88x-xj24

---
From sbomify Insights: https://insights.sbomify.com/GHSA-3pw3-v88x-xj24/
Summaries are generated and may contain mistakes; the official description above is the record.
