Back to skill

Security audit

Vast Ai

Security checks for vulnerabilities and agentic risk

Overview

This skill is a real VAST.ai GPU rental wrapper, but it can create paid cloud instances without code-enforced confirmation, limits, or teardown support.

Review carefully before installing. Use a limited VAST.ai API key if possible, keep DEBUG unset, rotate the key if it has appeared in logs, and only run rent after manually verifying the offer, hourly price, balance, and how you will stop or destroy the instance. The publisher should add code-level confirmation, spending limits, safer logging, dependency updates, and an exposed teardown path before this is treated as low risk.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
src/adapter.ts:14
Finding
Billable GPU Rentals Bypass Documented Confirmation and Balance Safeguards## Vulnerability Details **File Location**: `src/adapter.ts:14-16` **Vulnerability Type**: Missing authorization and financial precondition enforcement **Risk Level**: Medium ### Vulnerable Code ```typescript case 'rent': // params: { id: number, image: string } return await client.rent(params.id, params.image); ``` The safeguards that should precede this operation appear only in `SKILL.md:10-17`: ```markdown - **Pre-flight Check**: Before renting, call `balance` to ensure the user has sufficient funds. - **Step 2**: Search for offers and present the top 3 cheapest options to the user. - **Step 3**: Upon confirmation, call `rent`. - **Reporting**: If credit is below $5.00, warn the user after every successful rental. ``` ### Technical Analysis The `rent` action creates a billable VAST.ai instance, but the adapter does not enforce the documented user-confirmation or balance-check requirements. It accepts an action and parameters from its caller and immediately invokes `client.rent()`. Security-sensitive and financially consequential controls cannot safely rely solely on natural-language agent instructions. A direct API caller, an incorrectly behaving agent, or manipulated upstream input can invoke the adapter without following `SKILL.md`. The implementation also does not reject malformed or unexpected rental identifiers and does not enforce a minimum balance or spending limit. ### Attack Path 1. An attacker or erroneous upstream agent gains the ability to invoke `VastSkill.execute()` with the victim's execution context. 2. The caller submits the `rent` action with an offer ID and optional image: ```typescript VastSkill.execute("rent", { id: 12345, image: "pytorch/pytorch" }, context) ``` 3. The adapter does not require proof of user confirmation. 4. The adapter does not call `getBalance()` or verify that sufficient credit is available. 5. `VastClient.rent()` issues a `PUT` request t ...[truncated 685 chars]
Remediation
## Remediation Suggestions 1. Enforce confirmation in code rather than relying on agent instructions. Require a short-lived, server-generated confirmation token bound to the selected offer, image, price, account, and expiration time. 2. Query the current account balance immediately before creating the instance and reject the operation if the configured minimum balance or spending policy is not satisfied. 3. Obtain the authoritative offer price immediately before rental and enforce an explicit user-approved maximum hourly price. 4. Validate `params.id` as a positive safe integer and restrict image values to an approved allowlist or require explicit confirmation for custom images. 5. Add account-level controls such as maximum hourly burn, maximum concurrent instances, and per-operation spending limits. 6. Return the required low-credit warning from the implementation so it cannot be omitted by the calling agent. 7. Record a security audit event for each attempted and completed rental without recording the API key. 8. Add automated tests proving that rentals fail without confirmation, with expired or mismatched confirmation tokens, and when financial limits are exceeded.

T09 · Insecure Skill Coding Practices

Warning
Location
src/cli.ts:33
Finding
Debug Error Logging Can Expose the VAST.ai Bearer Token## Vulnerability Details **File Location**: `src/cli.ts:33-35` **Related Secret Assignment**: `src/DynamicApi.ts:180-182` **Vulnerability Type**: Sensitive credential exposure through verbose error logging **Risk Level**: Medium ### Vulnerable Code `src/cli.ts:33-35` logs the complete error object when `DEBUG` is enabled: ```typescript } catch (error: any) { console.error('Error executing action:', error.message || error); // Print full error if verbose if (process.env.DEBUG) console.error(error); process.exit(1); } ``` The bearer credential is assigned to Axios's default request headers in `src/DynamicApi.ts:180-182`: ```typescript setAuthToken(token: string) { this.axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${token}`; } ``` ### Technical Analysis Axios errors commonly include the request configuration used for the failed operation. That configuration can contain request headers, including the `Authorization` header populated by `setAuthToken()`. Printing the complete error object without redaction can therefore disclose the VAST.ai API key to stderr. In production, CI, container, or agent environments, stderr is often retained by centralized logging systems and may be accessible to more users or services than the original secret. The ordinary error message at line 33 is substantially safer, but the conditional full-object logging at line 35 defeats that protection whenever the `DEBUG` environment variable is set to any non-empty value. ### Attack Path 1. The CLI starts with a valid `VAST_API_KEY` and a non-empty `DEBUG` environment variable. 2. `VastClient` places the API key in Axios's default `Authorization` header. 3. An API request is made to VAST.ai. 4. A network failure, timeout, rejected request, rate-limit response, or other Axios error occurs. An attacker who can influence network conditions or request parameters may deliberately trigger su ...[truncated 1010 chars]
Remediation
## Remediation Suggestions 1. Never log the complete Axios error object. Emit only an allowlisted set of fields, such as error name, safe message, error code, and HTTP status. 2. Implement centralized recursive redaction for `Authorization`, `Proxy-Authorization`, cookies, API keys, tokens, and sensitive request bodies before any diagnostic object is logged. 3. Replace the current debug block with sanitized output, for example: ```typescript if (process.env.DEBUG) { console.error({ name: error?.name, message: error?.message, code: error?.code, status: error?.response?.status }); } ``` 4. Ensure logging infrastructure applies an additional secret-redaction layer before retaining or forwarding output. 5. Treat any key that may already have appeared in debug logs as compromised: revoke or rotate it and remove exposed log records according to the organization's incident-response policy. 6. Add tests using a synthetic bearer token to verify that neither normal nor debug error output contains the token or the `Authorization` header. 7. Limit access to CI, container, and centralized logs and configure appropriate retention periods.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (16)

Known Vulnerable Dependency: axios==1.13.4 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
97% confidence
Finding
The lockfile pins axios 1.13.4, and the supplied advisory set includes high-severity issues such as NO_PROXY normalization bypass leading to SSRF and prototype-pollution-related man-in-the-middle or credential theft scenarios. Because this is a network client library commonly used to make outbound HTTP requests, a vulnerable version can directly affect request routing, proxy handling, header safety, and trust boundaries in an agent skill.

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
93% confidence
Finding
The lockfile contains form-data 4.0.5, which is flagged for CRLF injection through unescaped multipart field names and filenames. If any part names or filenames can be influenced by external input, an attacker may be able to inject malformed multipart headers or manipulate downstream parsers, potentially leading to request smuggling-style effects, header injection, or unexpected server-side behavior.

Known Vulnerable Dependency: axios==1.13.4 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
98% confidence
Finding
The package explicitly depends on axios 1.13.4, and the static analysis reports multiple known advisories affecting that version, including SSRF-related and prototype-pollution/MITM-adjacent issues. Because this skill appears to interact with an external service (vast.ai), a vulnerable HTTP client increases the chance that hostile input, proxy settings, or request handling edge cases could be abused to leak credentials, bypass network controls, or tamper with traffic.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README explicitly documents a `rent` command that creates GPU instances but does not warn that this action provisions billable cloud resources and can incur ongoing charges. In an agent-skill context, omission of cost/safety warnings is more dangerous because an LLM-driven agent or inattentive user may execute the command directly, leading to unintended financial loss.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This code defines safety-impacting remote actions, including creating and deleting cloud instances, but provides no confirmation prompt, logging, print statement, or explanatory docstring/comment warning the user about those effects. These operations can incur cost or destroy running resources, so the absence of any disclosure matches the missing-warning criterion for code files.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The code reads an API credential from `context.API_KEY` to initialize the VAST client, but there is no user-facing log, prompt, comment, or docstring disclosing that sensitive credential material is being used. Under the code-file criteria, access to sensitive environment variables or credentials should be flagged when there is no visible disclosure.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The `rent` action performs a billable, state-changing operation immediately from caller-supplied parameters with no confirmation, authorization check, policy gate, spending limit, or dry-run safeguard. In an agent setting, ambiguous prompts, prompt injection, or accidental tool invocation could cause unintended GPU rentals and direct financial loss.

Known Vulnerable Dependency: follow-redirects==1.15.11 — 1 advisory(ies): CVE-2026-40895 (follow-redirects leaks Custom Authentication Headers to Cross-Domain Redirect Ta)

Low
Category
Supply Chain
Confidence
91% confidence
Finding
The lockfile includes follow-redirects 1.15.11, which is flagged for leaking custom authentication headers across cross-domain redirects. In an agent or integration context, outbound requests may carry API keys or bearer tokens, so improper redirect handling can expose credentials to attacker-controlled destinations if redirects are followed automatically.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"license": "ISC",
  "type": "commonjs",
  "dependencies": {
    "axios": "^1.13.4",
    "limiter": "^3.0.0",
    "minimist": "^1.2.8"
  },
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"type": "commonjs",
  "dependencies": {
    "axios": "^1.13.4",
    "limiter": "^3.0.0",
    "minimist": "^1.2.8"
  },
  "devDependencies": {
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"dependencies": {
    "axios": "^1.13.4",
    "limiter": "^3.0.0",
    "minimist": "^1.2.8"
  },
  "devDependencies": {
    "@types/minimist": "^1.2.5",
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"minimist": "^1.2.8"
  },
  "devDependencies": {
    "@types/minimist": "^1.2.5",
    "@types/node": "^25.2.0",
    "typescript": "^5.9.3"
  }
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
},
  "devDependencies": {
    "@types/minimist": "^1.2.5",
    "@types/node": "^25.2.0",
    "typescript": "^5.9.3"
  }
}
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"devDependencies": {
    "@types/minimist": "^1.2.5",
    "@types/node": "^25.2.0",
    "typescript": "^5.9.3"
  }
}
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Missing User Warnings

Low
Confidence
77% confidence
Finding
The getBalance method retrieves account-level information including credit, email, and account ID from the remote API, which is sensitive user/account data. In this file there is no user-facing warning, logging, or docstring/comment disclosing that such account data will be accessed and returned.

Static analysis

No suspicious patterns detected.