Back to skill

Security audit

cargo-content

Security checks for vulnerabilities and agentic risk

Overview

Review is needed because file-upload examples also redeploy agents with settings that could remove their existing tools and capabilities.

Before using attachment examples, preserve the agent's existing settings and review all deployment changes. Confirm the active workspace and intended files before writes, deletion, or sharing. Uploads normally send supported files to OpenAI and mirror them into Git; use put for new files that should remain unindexed and unmirrored. Prefer a reviewed CLI version.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The command configures an agent's resources rather than managing workspace files directly. This is precisely the agent-wiring capability that the declared description explicitly excludes and delegates to cargo-ai. The deployment instruction is a comment, not an executed command, but the update-draft command alone establishes the mismatch.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The upload step matches the declared file-management purpose. However, the subsequent commands modify and deploy an agent, directly crossing the description's explicit boundary that wiring files or libraries into agents should use a different skill. These are substantive agent-management operations, not supporting details of file storage or knowledge-library management.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
86% confidence
Finding

Although the description broadly mentions managing files, its stated operations cover uploading, indexing, storing, reading, listing, and sharing—not removal. The supplied command performs deletion rather than a supporting implementation detail of those operations.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 93)May include surrounding context.

cargo-ai content file download reports/2026-q3/summary.pdf --out ./copy.pdf cargo-ai content file url reports/2026-q3/summary.pdf --expires 3600 [--download] # → { url, expiresAt, publicUrl? } cargo-ai content file visibility reports/2026-q3/summary.pdf public # private revokes the public link at once cargo-ai content file rm reports/2026-q3/summary.pdf

text

| Option | `upload` / web app / `defineFile` | `put` / objects API / worker / `writeFile` node | Agent write |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/objects.md (reported line 66)May include surrounding context.

cargo-ai content file download reports/2026-q3/summary.pdf --out ./copy.pdf # stdout without --out cargo-ai content file url reports/2026-q3/summary.pdf --expires 3600 --download cargo-ai content file visibility reports/2026-q3/summary.pdf public # or private: revokes the public link at once cargo-ai content file rm reports/2026-q3/summary.pdf

text

`put` takes any size (multipart upload to the workspace area, then `files/import`). `--content-type` defaults from the extension. `--mirror-to-context` can only turn mirroring on; leaving it off keeps an existing file's setting. `ls` matches a string prefix, as in S3: `reports/` lists the folder and everything under it; omit it to list every file.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · SKILL.md (reported line 102)May include surrounding context.

md
| `mirrorToContext` | `true` | `false` | always `false` |
| `visibility` | `private` | `private` | always `private` |

The same files over HTTP are **objects** — `PUT` / `GET` (`?meta=true` for details) / `DELETE /v1/content/objects/<path>`, `GET /v1/content/objects?prefix=` — and from a worker `createCargoObjects(env)` (`@cargo-ai/worker-sdk`); in a play, the `writeFile` / `readFile` / `getFileUrl` nodes; on an agent, a writable folder (`capability_file_write`). All of it in [`references/objects.md`](references/objects.md).

## Libraries

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/objects.md (reported line 79)May include surrounding context.

md
|---|---|
| `PUT /v1/content/objects/<path>` | Write. Body is the raw bytes sent as `application/octet-stream`, **≤ 100 MB**; query `contentType`, `indexMode`, `visibility`, `mirrorToContext=true\|false`. `201 { file, path }`; failure `reason`: `invalidPath`, `folderNotFound`, `folderReadOnly`, `workspaceNotFound`, `noBody`. |
| `GET /v1/content/objects/<path>` | The bytes; `?meta=true` returns `{ file, path }` instead. |
| `DELETE /v1/content/objects/<path>` | Remove. |
| `GET /v1/content/objects?prefix=&cursor=&limit=` | List, `limit` 1–1000 (default 100); `invalidCursor` on a stale cursor. |
| `POST /v1/content/files/import` | Adopt bytes a workspace multipart upload already put in S3: `{ s3Filename, path, contentType, indexMode?, mirrorToContext?, visibility? }`. The route for anything over 100 MB. `invalidS3Filename` when the key is not this workspace's. |
| `POST /v1/content/files/<uuid>/url` | Signed URL: `{ expiresInSeconds? (1–10800), download? }`. |

MCP server referenced without pinned version: 'npx @cargo-ai/cli'.

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

The bootstrap recommends installing or executing an unpinned npm package, allowing the code used by the skill to change without review. Although this is a CLI rather than an MCP server, a compromised future release could execute with the invoking user's access to local files and Cargo credentials.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 135)May include surrounding context.

md
## Critical rules

- **A signed URL is unauthenticated.** Anyone holding it opens the file until it expires (default 3600 s, max 10800 s). A `public` file adds a stable no-auth link, `https://api.getcargo.io/files/public/<uuid>/<name>`, that works until the file is made private or deleted. Hand out either only when the user asked for the file to be shared, and never for record-level personal data.
- **`upload` and `put` default differently.** `upload` indexes (`vectorStore`, sent to OpenAI) and mirrors into the context repo; `put` does neither. A type OpenAI won't index (video, for one) is still stored under `vectorStore`, unindexed, rather than failing the upload. A `put` file is not searchable by an agent — `capability_file_search` skips it and `capability_file_analyze` refuses it — until written with `--index vectorStore`.
- **A mirrored file is in git.** `mirrorToContext: true` commits the file to the context repository under `.files/`; pass `--index none` and keep mirroring off (

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/objects.md (reported line 46)May include surrounding context.

md
## Links

- **Signed URL** — `content file url <path>`, `POST /v1/content/files/<uuid>/url`, the `getFileUrl` node, `objects.url()`. **Anyone holding it can open the file, no auth**, until it expires: default 3600 s, maximum 10800 s (3 h). `--download` / `download: true` sets `Content-Disposition: attachment`. Returns `{ url, expiresAt, publicUrl? }`.
- **Public link** — a `public` file also answers at `https://api.getcargo.io/files/public/<uuid>/<name>` (the trailing name is cosmetic). It is stable and unauthenticated; each hit redirects to a fresh 5-minute signed URL with `Cache-Control: no-store`. Making the file `private`, deleting it, or it being temporary makes the link 404 **at once**. `publicUrl` appears in `url` results only while the file is public.

Treat both as publishing the file. Never hand out a signed URL or make a file public unless the user asked for the file to be shareable, and never for a file holding record-level personal data.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/response-shapes.md (reported line 68)May include surrounding context.

// content file url reports/2026-q3/summary.pdf { "url": "https://…signed…", "expiresAt": "2026-10-23T13:00:00.000Z", "publicUrl": "https://api.getcargo.io/files/public//summary.pdf" } // publicUrl only while the file is public

text

`put` failures carry a `reason`: `invalidPath`, `folderNotFound`, `folderReadOnly`, `invalidS3Filename`, `workspaceNotFound`. `url` on a missing file → `fileNotFound`. `download` writes the raw bytes (stdout, or `--out`), not JSON.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · SKILL.md (reported line 138)May include surrounding context.

md
ked for the file to be shared, and never for record-level personal data.
- **`upload` and `put` default differently.** `upload` indexes (`vectorStore`, sent to OpenAI) and mirrors into the context repo; `put` does neither. A type OpenAI won't index (video, for one) is still stored under `vectorStore`, unindexed, rather than failing the upload. A `put` file is not searchable by an agent — `capability_file_search` skips it and `capability_file_analyze` refuses it — until written with `--index vectorStore`.
- **A mirrored file is in git.** `mirrorToContext: true` commits the file to the context repository under `.files/`; pass `--index none` and keep mirroring off (`put`) for files that should stay in Content.
- **A path write overwrites without asking.** The newest file of that name in that folder is replaced in place, and its `uuid` (and every agent resource pointing at it) now serves the new bytes. A read-only (connector) folder refuses with `folderReadOnly`.

## Attaching to an agent

The examples configure and deploy agent resources despite the manifest explicitly excluding agent wiring.

Medium
Category
Excessive Agency
Confidence
99% confidence
Finding

These examples extend a file-upload workflow into agent configuration and deployment despite the declared delegation of agent wiring to another skill. If followed for an existing agent, the deployment command supplies a fixed model and empty action, MCP-client, and capability arrays, risking unintended changes to the live agent beyond attaching a file.

Content

No source excerpt is available for this finding.