Back to skill

Security audit

AgentSpend

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for paid external API calls, but it asks agents to run an unpinned npm CLI and enables broad paid requests with locally stored credentials.

Review this before installing in environments with sensitive files or strict spending controls. Prefer a pinned reviewed CLI version, set a low weekly budget and domain allowlist, use `--max-cost` for every paid request, and avoid sending secrets, private headers, or regulated data through paid endpoints unless you trust AgentSpend Cloud and the target provider.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (2)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:19
Finding

Unpinned Remote Package Execution Through npx

Content
View full analysis
"` 2. Confirm cost and constraints with the user (`--max-cost`, budget, allowlist) 3. `npx agentspend pay --method ... --header ... --body ... --max-cost ...` ## Setup ```bash npx agentspend configure ``` ``` ### Technical Analysis The Skill directs the Agent to execute `agentspend` through `npx` without specifying an exact package version. If the package is not already available locally, `npx` can retrieve and execute the version currently published in the npm registry. Consequently, the code executed by an Agent following these instructions is not necessarily the audited source. A later compromised, malicious, or unexpectedly changed package release could replace the effective implementation without any modification to the Skill itself. This is a supply-chain trust issue rather than evidence that the currently reviewed package is malicious. The reviewed `package.json` uses ordinary npm dependencies and contains no lifecycle scripts, but the unpinned `npx` workflow remains mutable after review. ### Attack Path 1. An attacker compromises the npm publisher account, registry package, or a future package release. 2. The attacker publishes a modified version of `agentspend` containing malicious executable code. 3. An Agent follows the Skill's default workflow and invokes an unversioned command such as `npx agentspend search`. 4. If no suitable local package is present, `npx` downloads the currently resolved package version. 5. The downloaded package executes with the privileges of the user running the Agent. 6. Malicious code could access user-readable files, environment variables, AgentSpend credentials, and network resources available to that account. ### Impact Assessment Successful exploi ...[truncated 465 chars]
Remediation
View remediation
" npx --yes agentspend@0.2.2 configure ``` 2. Prefer installing dependencies from a committed lockfile and invoking the locally installed binary: ```bash npm ci ./node_modules/.bin/agentspend search "" ``` 3. Publish and verify package integrity metadata or signatures where supported. 4. Add an update-review process so version changes require a new security review before the Skill instructions are updated. 5. Avoid semver ranges for security-sensitive runtime dependencies when producing a reproducible audited artifact. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
src/lib/credentials.ts:66
Finding

Pending Onboarding Token Is Written Without Explicit Restrictive File Permissions

Content
View full analysis
{ await mkdir(CREDENTIALS_DIR, { recursive: true, mode: 0o700 }); await writeFile( PENDING_CONFIGURE_FILE, `${JSON.stringify({ token, created_at: new Date().toISOString() }, null, 2)}\n`, "utf-8", ); } ``` ### Technical Analysis The pending configuration token is written without an explicit file mode and is not subsequently changed to mode `0600`. Its effective permissions therefore depend on the process umask and the host filesystem. The requested `0700` directory mode provides partial protection when the directory is newly created. However, `mkdir(..., { recursive: true, mode: 0o700 })` does not necessarily correct the permissions of a pre-existing `~/.agentspend` directory. If that directory already has permissive permissions, the pending token file may be readable by another local account. This differs from `credentials.json`, which is explicitly changed to mode `0600` after writing. The pending token is a temporary capability used to query and claim an onboarding session, so it should receive equivalent protection. ### Attack Path 1. The `~/.agentspend` directory already exists with permissions that allow another local user to traverse or read it, or the process runs with a permissive umask. 2. The user runs `agentspend configure`. 3. `pending-configure.json` is created without an explicit restrictive mode. 4. Another local user reads the `cfs_` configuration token. 5. The local attacker uses the token against the configuration status or claim endpoints before it expires. 6. Depending on server-side claim semantics and session state, the attacker may observe or interfere with onboarding and potentially cause denial of service or unauthorized session claiming. Exploita ...[truncated 749 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (26)

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The skill explicitly states that credentials are saved to ~/.agentspend/credentials.json, creating a local credential-storage target that could be read by other processes, accidentally exposed through backups, or mishandled if file permissions are weak. Because the same skill also enables payment-backed external actions, compromise of this file could allow unauthorized spending or account takeover of the service context.

Content

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

npx agentspend configure

text

Opens a URL to add a credit card and set a weekly spending limit. Saves credentials to `~/.agentspend/credentials.json`.

If already configured, re-running opens the dashboard to update settings.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 23)May include surrounding context.

md
import type { Credentials } from "../types.js";

const CREDENTIALS_DIR = path.join(os.homedir(), ".agentspend");
const CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, "credentials.json");
const PENDING_CONFIGURE_FILE = path.join(CREDENTIALS_DIR, "pending-configure.json");

export async function readCredentials(): Promise<Credentials | null> {

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/lib/credentials.ts (reported line 7)May include surrounding context.

ts
import type { Credentials } from "../types.js";

const CREDENTIALS_DIR = path.join(os.homedir(), ".agentspend");
const CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, "credentials.json");
const PENDING_CONFIGURE_FILE = path.join(CREDENTIALS_DIR, "pending-configure.json");

export async function readCredentials(): Promise<Credentials | null> {

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
---
name: agentspend
description: Use this skill when you need to: search the web, generate images or pictures, create videos, scrape or read a webpage, take a screenshot of a website, get stock prices or financial data, look up business info, find news articles, convert files, get weather data, or access any external API that requires payment. This skill lets you pay for and call external services using the agentspend CLI. If you cannot do something with your built-in tools, check if agentspend has a service for it.
---

# When To Use This Skill

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill is triggered for a very broad set of generic web, API, scraping, media-generation, and financial-data tasks, which can cause it to be invoked when a safer built-in capability or narrower tool should be used instead. In this context, overbroad invocation is dangerous because the skill can spend money, transmit user data externally, and encourage execution of the unpinned CLI across many routine tasks.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The skill repeatedly instructs use of npx agentspend without pinning a specific package version. Because npx resolves and executes code from the registry at runtime, a future malicious or compromised release could execute arbitrary code on the host, making this a real supply-chain risk in a skill that is designed to be invoked frequently.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

This command uses unpinned npx agentspend, which allows execution of whatever version the npm registry serves at runtime. In a payment-enabling skill, that creates a meaningful remote code execution and supply-chain exposure if the package is ever hijacked or maliciously updated.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The setup step invokes an unversioned npm package via npx, so the exact code executed is not fixed or reviewable over time. Since setup handles onboarding and payment configuration, compromise here could expose sensitive credentials or alter security settings.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The setup and usage guidance mentions adding a credit card and storing credentials locally, but it does not clearly warn that user prompts, request bodies, URLs, and headers may be transmitted to third-party paid services. In a skill centered on external API calls and payment, this omission can lead to accidental disclosure of sensitive data and underinformed consent by both users and operators.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The pay command is documented with an unpinned npx package reference, creating a supply-chain execution risk each time a paid request is made. Because this command can send headers, bodies, and payment-related metadata, a compromised package could exfiltrate data or initiate unauthorized actions.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

This check example again relies on unpinned runtime package resolution. Even though it is a pricing check, the command may still transmit request headers and bodies, so executing an unreviewed future version could leak sensitive request content or perform arbitrary code execution.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The search command uses npx agentspend without a version pin, exposing users to package substitution or malicious future releases. While search is less privileged than payment setup, it still executes external code on the local host and can be a foothold for compromise.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The status command executes an unpinned package from npm, so the code path is mutable and susceptible to supply-chain compromise. Because status may access account and spending information, a malicious package could harvest sensitive account metadata.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The configure command is especially sensitive because it opens the onboarding/dashboard flow and influences budget, allowlist, and payment method settings. Invoking it through unpinned npx means a compromised upstream package could manipulate those settings or steal payment-related information.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

This repeated reference to npx agentspend configure remains a real supply-chain risk because it fetches executable code without a fixed version. The context amplifies concern since the command affects domain allowlists and spending controls that protect downstream usage.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The documentation again recommends an unpinned npx invocation, making the executed code dependent on the current npm registry state rather than a reviewed artifact. This weakens reproducibility and creates a practical package-compromise vector.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

This troubleshooting guidance instructs rerunning npx agentspend configure without a version pin, preserving the same supply-chain weakness even in error recovery flows. Users may invoke it under pressure, increasing the chance they run compromised code without scrutiny.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The error-handling section still directs execution of an unpinned npm package. Attackers often benefit from such repeated, normalized patterns because users stop noticing that remote code is being fetched dynamically.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

This final repeated npx agentspend reference is another instance of the same unpinned execution issue. In aggregate, the skill normalizes insecure package execution throughout setup, use, and recovery, which materially increases exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The markdown file states that credentials are stored at ~/.agentspend/credentials.json but does not include any warning that this file contains sensitive secrets or should be protected. Because the skill description discusses credential storage, a brief user-facing warning about safeguarding or restricting access to that file would improve safety and privacy awareness.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The dependency uses a caret version range, which permits automatic installation of newer semver-compatible releases. This increases supply-chain risk because a compromised or vulnerable upstream release could be pulled in without an explicit review, especially for a CLI that users install and execute locally.

Content

Scanner excerpt · package.json (reported line 17)May include surrounding context.

json
"typecheck": "tsc -p tsconfig.json --noEmit"
  },
  "dependencies": {
    "bcryptjs": "^2.4.3",
    "commander": "^12.1.0"
  },
  "devDependencies": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The commander package is specified with a caret range, allowing semver-compatible updates to be resolved automatically. For a distributable CLI, this creates a supply-chain exposure where an unintended upstream release may alter runtime behavior or introduce malicious code.

Content

Scanner excerpt · package.json (reported line 18)May include surrounding context.

json
},
  "dependencies": {
    "bcryptjs": "^2.4.3",
    "commander": "^12.1.0"
  },
  "devDependencies": {
    "@types/bcryptjs": "^2.4.6",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
81% confidence
Finding

The devDependency is not pinned, so development and build environments may resolve different versions over time. While this is less severe than a runtime dependency, compromised build-time packages can still affect produced artifacts or developer environments.

Content

Scanner excerpt · package.json (reported line 21)May include surrounding context.

json
"commander": "^12.1.0"
  },
  "devDependencies": {
    "@types/bcryptjs": "^2.4.6",
    "@types/node": "^22.10.2",
    "tsx": "^4.19.2",
    "typescript": "^5.7.2"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
81% confidence
Finding

Using a caret range for @types/node allows build-time dependency drift, which can reduce reproducibility and marginally increase supply-chain risk. Although type packages do not ship directly at runtime, they still execute within the development ecosystem and can affect CI or local builds if compromised.

Content

Scanner excerpt · package.json (reported line 22)May include surrounding context.

json
},
  "devDependencies": {
    "@types/bcryptjs": "^2.4.6",
    "@types/node": "^22.10.2",
    "tsx": "^4.19.2",
    "typescript": "^5.7.2"
  }

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
86% confidence
Finding

The tsx devDependency is unpinned and is an executable development tool, so semver-range updates can introduce compromised code into local development or CI execution. Because this tool runs code during development, it is somewhat more sensitive than passive type-only packages.

Content

Scanner excerpt · package.json (reported line 23)May include surrounding context.

json
"devDependencies": {
    "@types/bcryptjs": "^2.4.6",
    "@types/node": "^22.10.2",
    "tsx": "^4.19.2",
    "typescript": "^5.7.2"
  }
}

Static analysis

No suspicious patterns detected.