GHSA-P7MM-R948-4Q3Q

GHSA-P7MM-R948-4Q3Q is a medium-severity security vulnerability in @paperclipai/server (npm), affecting versions < 2026.416.0. It is fixed in 2026.416.0.

Summary

Paperclip: Approval decision attribution spoofing via client-controlled decidedByUserId in paperclip server

Impact

  • Forged governance audit trail. Any board user with access to a company can record approval, rejection, or revision-request decisions under any arbitrary user identifier, including other legitimate board users of that company. Approvals gate security-sensitive actions (agent hiring, which grants execution privileges and assigns a monthly spend budget), and the approvals.decidedByUserId column is the authoritative record of who authorized each decision.
  • Budget-policy attribution forgery. For hire_agent approvals that carry a monthly budget, budget_policies.createdByUserId / updatedByUserId are also populated from the same attacker-controlled string, spreading the forgery to spend-authorization audit columns.
  • Non-repudiation break. A board user can frame another board user for approving/rejecting a hire, undermining accountability for governance actions. The parallel activity_log entry does preserve the true actor, but any reviewer inspecting the approval itself (not the activity log) will see the forged attribution as fact.
  • Scope. Limited to board users who already have company access; does not escalate privileges, does not leak data, and does not change whether the decision itself gets applied. Integrity impact is Low (attribution only, not decision content); confidentiality and availability are unaffected.

GHSA-P7MM-R948-4Q3Q has a CVSS score of 4.3 (Medium). The vector is network-reachable, low privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (2026.416.0); upgrading removes the vulnerable code path.

Affected versions

@paperclipai/server (< 2026.416.0)

Security releases

@paperclipai/server → 2026.416.0 (npm)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

See it in your environment

Remediation advice

Drop decidedByUserId from the request schema entirely and derive it server-side from the authenticated actor. Treat req.body.decidedByUserId as untrusted and ignore it.

packages/shared/src/validators/approval.ts:

export const resolveApprovalSchema = z.object({
  decisionNote: z.string().optional().nullable(),
  // decidedByUserId removed, server derives from req.actor
});

export const requestApprovalRevisionSchema = z.object({
  decisionNote: z.string().optional().nullable(),
});

server/src/routes/approvals.ts (apply to /approve, /reject, /request-revision):

router.post("/approvals/:id/approve", validate(resolveApprovalSchema), async (req, res) => {
  assertBoard(req);
  const id = req.params.id as string;
  if (!(await requireApprovalAccess(req, id))) {
    res.status(404).json({ error: "Approval not found" });
    return;
  }
  const decidedBy = req.actor.userId ?? "board";   // trust the session, not the body
  const { approval, applied } = await svc.approve(id, decidedBy, req.body.decisionNote);
  ...
});

Repeat the same const decidedBy = req.actor.userId ?? "board"; substitution at approvals.ts:238 (/reject) and :269 (/request-revision). No change is needed inside approvalService, it already accepts the value as a parameter, and this also ensures the forged value cannot reach budgets.upsertPolicy at approvals.ts:155. Existing callers that currently pass a body decidedByUserId can be updated to stop sending it (it is already effectively redundant with the session).

Frequently Asked Questions

  1. What is GHSA-P7MM-R948-4Q3Q? GHSA-P7MM-R948-4Q3Q is a medium-severity security vulnerability in @paperclipai/server (npm), affecting versions < 2026.416.0. It is fixed in 2026.416.0.
  2. How severe is GHSA-P7MM-R948-4Q3Q? GHSA-P7MM-R948-4Q3Q has a CVSS score of 4.3 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
  3. Which versions of @paperclipai/server are affected by GHSA-P7MM-R948-4Q3Q? @paperclipai/server (npm) versions < 2026.416.0 is affected.
  4. Is there a fix for GHSA-P7MM-R948-4Q3Q? Yes. GHSA-P7MM-R948-4Q3Q is fixed in 2026.416.0. Upgrade to this version or later.
  5. Is GHSA-P7MM-R948-4Q3Q exploitable, and should I be worried? Whether GHSA-P7MM-R948-4Q3Q is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  6. What actually determines whether GHSA-P7MM-R948-4Q3Q is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  7. How do I fix GHSA-P7MM-R948-4Q3Q? Upgrade @paperclipai/server to 2026.416.0 or later.

Other vulnerabilities in @paperclipai/server

CVE-2026-41208CVE-2026-41679

Stop the waste.
Protect your environment with Kodem.