GHSA-47wq-cj9q-wpmp
<img width="7007" height="950" alt="01-setup" src="https://github.com/user-attachments/assets/1596b8d1-8de5-4c21-b1d2-2db41b568d7e" /> > Isolated paperclip instance running in authenticated mode (default config) > on a clean Docker image matching commit b649bd4 (2026.411.0-canary.8, post > the 2026.410.0 patch). This advisory was verified on an unmodified build. ### Summary `POST /api/agents/:id/keys`, `GET /api/agents/:id/keys`, and `DELETE /api/agents/:id/keys/:keyId` (`server/src/routes/agents.ts` lines 2050-2087) only call `assertBoard` to authorize the caller. They never call `assertCompanyAccess` and never verify that the caller is a member of the company that owns the target agent. Any authenticated board user (including a freshly signed-up account with zero company memberships and no `instance_admin` role) can mint a plaintext `pcp_*` agent API token for any agent in any company on the instance. The minted token is bound to the **victim** agent's `companyId` server-side, so every downstream `assertCompanyAccess` check on that token authorizes operations inside the victim tenant. This is a pure authorization bypass on the core tenancy boundary. It is distinct from GHSA-68qg-g8mg-6pr7 (the unauth import → RCE chain disclosed in 2026.410.0): that advisory fixed one handler, this report is a different handler with the same class of mistake that the 2026.410.0 patch did not cover. ### Root Cause `server/src/routes/agents.ts`, lines 2050-2087: ```ts router.get("/agents/:id/keys", async (req, res) => { assertBoard(req); // <-- no assertCompanyAccess const id = req.params.id as string; const keys = await svc.listKeys(id); res.json(keys); }); router.post("/agents/:id/keys", validate(createAgentKeySchema), async (req, res) => { assertBoard(req); // <-- no assertCompanyAccess const id = req.params.id as string; const key = await svc.createApiKey(id, req.body.name); ... res.status(201).js
Properties
- ghsa_id
- GHSA-47wq-cj9q-wpmp
- severity
- critical
- summary
- Paperclip: Cross-tenant agent API token minting via missing assertCompanyAccess on /api/agents/:id/keys
- cvss_score
- 10
- cve_id
- GHSA-47wq-cj9q-wpmp
- cvss_vector
- CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
- is_ghsa_only
- true
- ghsa_published
- 2026-04-16T22:48:32Z
- source_url
- https://github.com/advisories/GHSA-47wq-cj9q-wpmp
- ghsa_updated
- 2026-04-16T22:48:33Z
Related Entities (7)
VULNERABLE_TO (1)
AFFECTS (1)
HAS_WEAKNESS (4)
REPORTED_BY (1)
Explore deeper with Ninja Signal's threat intelligence graph