Back to skill

Security audit

SkillzMarket

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed payment-enabled marketplace client, but it can use a wallet private key to make automatic paid requests to arbitrary URLs without strong scoping or confirmation.

Review carefully before installing. Use only a dedicated low-balance wallet, avoid sensitive payloads, and do not use `direct` unless you fully trust the endpoint and understand it may receive your data and request payment. Prefer a version with pinned dependencies, a lockfile, endpoint allowlisting, explicit payment confirmation, and spending limits.

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)

T09 · Insecure Skill Coding Practices

Error
Location
skillz-cli.ts:64
Finding

Unrestricted Remote Endpoints Can Trigger Wallet-Backed Payment Requests

Content
View full analysis

Vulnerability Details

File Location: skillz-cli.ts:64-79 and skillz-cli.ts:99-119
Vulnerability Type: Unvalidated payment-enabled remote endpoint and potential server-side request forgery
Risk Level: High

Vulnerable Code

typescript
const skill: Skill = await skillRes.json();

if (skill.isActive === false) {
  console.error(`Skill "${slug}" is not active`);
  process.exit(1);
}

console.error(`Calling ${skill.name} @ ${skill.endpoint} ($${skill.price} USDC)`);

// Set up payment client
const account = privateKeyToAccount(PRIVATE_KEY);
const client = new x402Client();
registerExactEvmScheme(client, { signer: account });
const paymentFetch = wrapFetchWithPayment(fetch, client);

try {
  const response = await paymentFetch(skill.endpoint, {
typescript
async function direct(url: string, input: string) {
  if (!PRIVATE_KEY) {
    console.error('Error: SKILLZ_PRIVATE_KEY not set');
    process.exit(1);
  }

  console.error(`Calling endpoint: ${url}`);

  // Set up payment client
  const account = privateKeyToAccount(PRIVATE_KEY);
  const client = new x402Client();
  registerExactEvmScheme(client, { signer: account });
  const paymentFetch = wrapFetchWithPayment(fetch, client);

  try {
    const response = await paymentFetch(url, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: input,
    });

Technical Analysis

The call command obtains skill.endpoint from the remotely configured marketplace API and passes it directly to a payment-enabled fetch operation. The direct command similarly accepts an arbitrary URL from the command line.

Neither path validates:

  • The URL protocol or destination hostname.
  • Whether the resolved address belongs to a loopback, private, link-local, or cloud metadata range.
  • The payment recipient, chain, token, or requested amount.
  • Whether the x402 payment challenge matches the catalog's displayed skill.price.
  • A per-call or cumulative spending li ...[truncated 2072 chars]
Remediation
View remediation

Remediation Suggestions

  1. Require https: for all remotely accessed payment endpoints and reject URLs containing embedded credentials.
  2. Introduce an explicit allowlist of trusted marketplace and skill endpoint hostnames.
  3. Resolve destination hostnames before connecting and reject loopback, private, link-local, multicast, reserved, and cloud metadata address ranges. Repeat this validation after redirects and mitigate DNS rebinding.
  4. Disable automatic redirects or validate every redirect destination before following it.
  5. For x402 challenges, enforce the expected network, asset, recipient, and maximum amount before authorizing a signature.
  6. Compare the challenge amount against the catalog price and reject any mismatch.
  7. Add configurable per-transaction and cumulative spending limits.
  8. Display the final payment recipient, asset, network, and amount and require explicit user confirmation before payment.
  9. Restrict or remove the direct command where arbitrary endpoint access is not a strict functional requirement.
  10. Use a dedicated wallet with minimal funds and narrowly scoped operational limits.

T08 · Insecure Dependencies

Warning
Location
package.json:26
Finding

Mutable and Unpinned Installation and Dependency Sources

Content
View full analysis

Vulnerability Details

File Location: package.json:26-32, README.md:11-25, SKILL.md:15-30, and skillz-call.sh:12-21
Vulnerability Type: Executable supply-chain exposure through mutable package and repository references
Risk Level: Medium

Vulnerable Code

package.json:26-32:

json
"dependencies": {
  "@x402/fetch": "^2.2.0",
  "@x402/evm": "^2.2.0",
  "viem": "^2.0.0",
  "tsx": "^4.21.0"
},
"devDependencies": {
  "@types/node": "^20.0.0"
}

README.md:11-25:

bash
npx add-skill github:skillzmarket/skill
bash
npx openskills install skillzmarket/skill
bash
git clone https://github.com/skillzmarket/skill
cp -r skill ~/.openclaw/skills/skillzmarket
cd ~/.openclaw/skills/skillzmarket && npm install

SKILL.md:15-30:

bash
npx tsx {baseDir}/skillz-cli.ts list
bash
npx tsx {baseDir}/skillz-cli.ts search "echo"
bash
npx tsx {baseDir}/skillz-cli.ts info "echo-service"
bash
npx tsx {baseDir}/skillz-cli.ts call "echo-service" '{"message":"hello"}'

skillz-call.sh:12-21:

bash
npx tsx "$SCRIPT_DIR/skillz-cli.ts" search "$@"
npx tsx "$SCRIPT_DIR/skillz-cli.ts" info "$@"
npx tsx "$SCRIPT_DIR/skillz-cli.ts" call "$@"
npx tsx "$SCRIPT_DIR/skillz-cli.ts" direct "$@"

Technical Analysis

Runtime dependencies are declared using caret ranges, allowing later compatible releases to be selected. The reviewed project does not include a lockfile, so exact dependency versions and integrity hashes are not fixed by the repository.

The documented installation methods invoke unversioned tools through npx, install from a mutable Git repository reference, and execute npm install without a committed lockfile. Runtime dispatch also repeatedly uses npx tsx; if the expected executable is unavailable locally, npx may offer to retrieve or resolve a package dynamically.

This is particularly sensitive because these components execute in a process that has access to `SKILLZ_PRIVATE ...[truncated 1562 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin production and development dependencies to exact reviewed versions rather than caret ranges.
  2. Generate, review, and commit a package lockfile containing resolved versions and integrity hashes.
  3. Use npm ci in installation and deployment workflows so dependency resolution must match the committed lockfile.
  4. Pin Git-based installation instructions to a reviewed commit hash or signed release tag.
  5. Pin versions of tools invoked with npx, or install them locally from the locked dependency set.
  6. Invoke the fixed local executable, such as node_modules/.bin/tsx, instead of allowing runtime package retrieval.
  7. Configure CI to reject unexpected lockfile changes and audit dependency updates before release.
  8. Use trusted registries, package provenance verification, and dependency integrity monitoring.
  9. Run installation and skill execution under a dedicated, minimally privileged account.
  10. Keep only limited funds in the wallet and avoid exposing unrelated credentials to the dependency process.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill is presented as a marketplace integration for discovering and calling Skillz Market skills, but it also exposes a direct <url> <json> command that can call arbitrary x402-enabled endpoints. That materially expands the trust boundary beyond the stated purpose and enables users or downstream agents to send data and payments to unreviewed external services.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The direct command allows sending paid POST requests to any user-supplied URL using the configured blockchain payment signer. In a skill meant for calling Skillz Market services, this bypasses marketplace trust boundaries and can route funds and sensitive request data to arbitrary attacker-controlled endpoints.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The arbitrary paid POST behavior is not necessary for the advertised purpose of searching and calling Skillz Market skills, so it materially expands the attack surface without justification. Because payment is wrapped around the fetch call, an attacker who can influence the URL can trigger unauthorized crypto-backed transactions to external services.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README encourages /skillzmarket direct <arbitrary URL> <payload> with automatic payment, but does not clearly warn that users may send sensitive request data to an untrusted endpoint and authorize cryptocurrency payments as part of the call. In the context of a skill explicitly configured with a wallet private key for automated USDC payments, this omission is especially dangerous because it can facilitate phishing-style endpoint substitution, unintended fund loss, and data exfiltration.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares capabilities that require environment access and outbound network access, but it does not explicitly scope or constrain those permissions in the manifest. Because this skill can initiate paid external calls and access a private key from the environment, the lack of declared tool scope makes the operational boundary unclear and increases the chance of over-broad or unexpected execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation does not prominently warn that invoking skills can trigger automatic cryptocurrency payments and transmit user-supplied data to third-party endpoints. In this context, missing consent and disclosure is security-relevant because users may unknowingly authorize spending or leak sensitive input to external services.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

Invoking tooling through npx tsx without a pinned package version creates a supply-chain risk because package resolution may fetch an unexpected or malicious version at runtime. In a skill that can access a wallet private key and make paid network calls, compromise of the runtime tool could directly expose credentials or trigger unauthorized payments.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

Using unpinned npx tsx again repeats the same supply-chain exposure: a transient or compromised package version could execute arbitrary code during skill use. Given that this skill processes a private key and performs cryptocurrency payments, the blast radius is materially higher than a normal CLI helper.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

This command also relies on unversioned npx tsx, preserving a runtime supply-chain execution path. If abused, an attacker could run arbitrary code in the context of the skill and potentially exfiltrate the wallet key or alter payment behavior.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding

The highest-risk command path (call) uses the same unpinned npx tsx execution model, which is especially dangerous because it is the path most likely to use the private key for automatic payments. A compromised runtime dependency here could directly sign transactions or redirect funds.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
87% confidence
Finding

The script invokes npx tsx without pinning an exact package version, so execution can vary over time and may fetch an unexpected or malicious package version depending on the environment. Because this wrapper dispatches external paid-skill operations, a compromised dependency or PATH-resolution issue could lead to arbitrary code execution when users invoke the skill.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
87% confidence
Finding

This npx tsx invocation is not version-pinned, which introduces supply-chain risk and non-reproducible execution. If npx resolves or installs a compromised tsx release, the attacker gains code execution in the context of a script that brokers calls to external monetized services.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
87% confidence
Finding

Using unpinned npx tsx here means the command may execute whatever package version is currently resolved, including a malicious or newly broken release. In the context of a cryptocurrency/payment-oriented skill, that increases the danger because a compromised runtime could tamper with calls, secrets, or payment-related workflows.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
87% confidence
Finding

The unpinned npx tsx call creates a dependency-confusion/supply-chain exposure because the executed tool version is not fixed by the script itself. Since this command supports a direct action and interfaces with external skills and payments, successful exploitation could result in arbitrary command execution, data theft, or transaction manipulation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
84% confidence
Finding

The shebang uses npx tsx, which resolves and executes a package dynamically rather than a pinned, vendored runtime. That creates a supply-chain risk: a compromised or unexpected tsx version could run attacker-controlled code when the CLI is invoked, especially in automation or fresh environments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The direct path transmits arbitrary caller-supplied data to an arbitrary URL with only a generic log message, which is insufficient given that the tool also authorizes payments. This can exfiltrate secrets or sensitive prompts and make users unknowingly send paid requests to attacker-controlled infrastructure.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency uses a caret version range, which allows newer minor or patch releases to be installed without explicit review. In a skill that performs external paid calls and cryptocurrency-related operations, automatic upgrades increase supply-chain risk because a compromised upstream release could alter payment or network behavior.

Content

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

json
"author": "Skillz Market",
  "license": "MIT",
  "dependencies": {
    "@x402/fetch": "^2.2.0",
    "@x402/evm": "^2.2.0",
    "viem": "^2.0.0",
    "tsx": "^4.21.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The @x402/evm package is not pinned to an exact version, so installs may pull in unreviewed updates. Because this skill is explicitly tied to automatic USDC/Base payment flows, dependency drift in blockchain/payment libraries raises meaningful supply-chain and transaction-safety concerns even if the package.json itself contains no direct malicious logic.

Content

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

json
"license": "MIT",
  "dependencies": {
    "@x402/fetch": "^2.2.0",
    "@x402/evm": "^2.2.0",
    "viem": "^2.0.0",
    "tsx": "^4.21.0"
  },

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

Using a ranged version for viem permits silent dependency changes across environments, which can introduce vulnerable or malicious code indirectly. Given the cryptocurrency integration context, even small upstream changes in signing, RPC, or chain-handling libraries can have outsized consequences if a compromised release is consumed.

Content

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

json
"dependencies": {
    "@x402/fetch": "^2.2.0",
    "@x402/evm": "^2.2.0",
    "viem": "^2.0.0",
    "tsx": "^4.21.0"
  },
  "devDependencies": {

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
84% confidence
Finding

The tsx dependency is also version-ranged, which creates the same general supply-chain exposure from unreviewed upstream releases. Its impact is lower than payment-specific libraries, but if used in execution or development workflows it can still introduce malicious code or instability during build/run stages.

Content

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

json
"@x402/fetch": "^2.2.0",
    "@x402/evm": "^2.2.0",
    "viem": "^2.0.0",
    "tsx": "^4.21.0"
  },
  "devDependencies": {
    "@types/node": "^20.0.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

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

json
"tsx": "^4.21.0"
  },
  "devDependencies": {
    "@types/node": "^20.0.0"
  }
}

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

All user-facing output, usage text, and error messages are emitted only in English, and the file provides no mechanism for language or locale selection. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy issue.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
skillz-cli.ts:6