Back to skill

Security audit

mcp-to-skill

Security checks for vulnerabilities and agentic risk

Overview

This skill has a legitimate MCP-to-skill conversion purpose, but it also runs inferred shell commands, fetches untrusted packages, and registers generated skills in persistent agent locations without enough user control.

Review carefully before installing. Use it only on MCP servers you trust or in a sandbox, do not allow automatic testing of inferred commands without inspecting each command and destination, pin dependencies before running package tools, and prefer environment variables or a secret manager over generated plaintext `secrets.json` files.

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 (3)

T08 · Insecure Dependencies

Error
Location
SKILL.md:48
Finding

Unpinned Third-Party Packages Are Installed and Executed

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:48-52 and SKILL.md:170-174
Vulnerability Type: Supply-chain exposure through unpinned dependencies
Risk Level: High

Vulnerable Code

bash
# Ensure mcp SDK is installed
pip show mcp > /dev/null 2>&1 || pip install mcp

python /path/to/skill-dir/mcp_inspector.py "<MCP command>" --output /tmp/mcp-inspector-output.json
bash
which npx && npx skills --version 2>/dev/null
bash
npx skills add <skill-path> -g -y

Technical Analysis

The workflow installs mcp without an exact version, integrity hash, lockfile, or explicitly trusted package index. It also invokes the generically named skills npm package through npx without pinning a reviewed version.

Running npx skills --version is not a safe local availability check: depending on npm configuration and cache state, npx can retrieve and execute the latest package from the configured registry. Both Python and npm packages can execute package-controlled code during installation or invocation.

Consequently, the code that runs is not fixed by the audited project and can change after review. Although there is no evidence that the current dependencies are malicious, the dependency-loading process creates a supply-chain execution channel.

Attack Path

  1. An attacker compromises the relevant registry package, publishing account, registry configuration, or network dependency resolution path.
  2. The user invokes the skill on a system where mcp is absent or where npx resolves the unpinned skills package.
  3. pip install mcp downloads and installs the attacker-influenced release, or npx skills --version downloads and executes attacker-controlled npm code.
  4. Installation hooks or package runtime code executes with the privileges of the agent process.
  5. The malicious dependency can access files, credentials, environment variables, an ...[truncated 566 chars]
Remediation
View remediation

Remediation Suggestions

  • Pin every dependency to an exact, reviewed version, including both mcp and the npm skills package.
  • For Python dependencies, use a locked requirements file with cryptographic hashes and install with pip install --require-hashes.
  • For npm dependencies, use a lockfile and invoke a locally installed, pinned binary rather than an unqualified npx package.
  • Specify and validate trusted package registries instead of inheriting arbitrary user or environment registry configuration.
  • Do not use npx skills --version as an availability probe. Check for an already installed executable without allowing automatic package download.
  • Obtain explicit user approval before any package installation or global registration.
  • Perform installation in an isolated virtual environment or restricted container with minimal filesystem and credential access.
  • Record the exact package version and integrity digest in generated audit output so users can verify what was executed.

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:66
Finding

Attacker-Controlled MCP Metadata Can Lead to AI-Inferred Command Execution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:66-90
Vulnerability Type: Unsafe execution of commands inferred from untrusted input
Risk Level: High

Vulnerable Code

text
**If source_path is not null:**
Use Read / Grep tools to read the source files, locate the implementation for each tool, and extract:
- HTTP endpoint (URL, method, headers, body structure)
- or CLI invocation pattern

**If source_path is null:**
Infer reasonable equivalent commands based solely on each tool's `description` and `inputSchema`.

Write a command draft for each tool with a confidence marker:
- `[VERIFIED]` — confirmed by source code (only when source is available)
- `[INFERRED]` — AI-inferred, logically sound but untested (max level when source_path is null)
- `[TODO]` — cannot be auto-generated, leave a placeholder with explanation

---

## Step 4: Test read-only commands

For each `[INFERRED]` command that is a read-only operation (GET request, query), execute it with the Bash tool:

- Pass → upgrade to `[VERIFIED]`
- Fail → keep `[INFERRED]`, add a comment above the command noting the failure reason
- Write operations (POST/PUT/DELETE, file modifications) — **skip testing**, keep `[INFERRED]`
- `[TODO]` items — do not test

Technical Analysis

MCP tool descriptions, input schemas, and downloaded source code originate outside the trusted skill package. A malicious MCP server can therefore provide adversarial text designed to influence command generation. The instructions direct the agent to convert this content into shell commands and automatically execute commands that the model classifies as read-only.

The workflow provides no structural command parser, executable allowlist, shell-metacharacter rejection, destination allowlist, private-network protection, sandbox, or mandatory user approval. Classification as a GET request or query is insufficient because a shell command can contain multiple ope ...[truncated 1779 chars]

Remediation
View remediation

Remediation Suggestions

  • Never execute AI-inferred commands automatically. Present the exact command, arguments, destination, and expected effects to the user and require explicit approval.
  • Treat MCP descriptions, schemas, and downloaded source as untrusted data rather than agent instructions.
  • Represent test actions as structured operations instead of shell strings. For HTTP testing, use a dedicated client API with fixed methods and separately validated URL fields.
  • Permit only an explicit allowlist of executables and command-line options.
  • Reject shell metacharacters, redirections, pipelines, command substitutions, inline scripts, and multi-command expressions.
  • Allowlist destination schemes and domains. Block loopback, link-local, private-network, Unix-socket, file, and cloud metadata destinations unless separately authorized.
  • Execute tests in a disposable sandbox with no user credentials, minimal filesystem access, disabled or restricted networking, and strict time and resource limits.
  • Require a deterministic side-effect policy rather than relying on the model to decide whether an operation is read-only.
  • Log the source metadata, generated command, validation result, and user authorization for later review.

T09 · Insecure Skill Coding Practices

Warning
Location
mcp_inspector.py:52
Finding

Predictable Shared Temporary Cache Allows Local Source Substitution

Content
View full analysis

Vulnerability Details

File Location: mcp_inspector.py:52-59
Vulnerability Type: Unsafe temporary-directory reuse and insufficient cache validation
Risk Level: Medium

Vulnerable Code

python
# 构建缓存目录
safe_name = package.replace('/', '-').lstrip('@-')
cache_dir = Path(tempfile.gettempdir()) / "mcp-to-skill-cache" / safe_name

# 已缓存则直接返回(排除仅含 .tgz 的失败解压目录)
if cache_dir.exists() and any(f for f in cache_dir.iterdir() if f.suffix != '.tgz'):
    return str(cache_dir)

cache_dir.mkdir(parents=True, exist_ok=True)

The downloaded archive is subsequently extracted into the same predictable location:

python
extract_result = subprocess.run(
    ['tar', 'xzf', str(tarball), '--strip-components=1'],
    capture_output=True, cwd=str(cache_dir), timeout=30
)

Technical Analysis

The inspector constructs a predictable path beneath the system temporary directory from a lossy package-name transformation. It considers the cache valid whenever the directory contains any entry whose suffix is not .tgz. It does not verify directory ownership, permissions, package identity, file integrity, symlinks, extraction completion, or a trusted manifest.

On systems where another local account or process can create or modify the relevant temporary path, an attacker can pre-populate the directory with crafted files. The function then returns that directory as authoritative package source without running npm pack. The package-name normalization can also produce collisions because different package strings may map to the same directory name.

In the documented workflow, the agent reads this source to infer CLI commands and HTTP requests. Therefore, substituted cache content can influence generated skill files and combine with the automatic testing behavior to induce execution of attacker-selected operations.

Attack Path

  1. A local attacker predicts the cache path from the npm package name.

...[truncated 1265 chars]

Remediation
View remediation

Remediation Suggestions

  • Store cached data in a per-user cache directory with mode 0700, rather than a broadly shared predictable temporary path.
  • Create a fresh extraction directory using a secure primitive such as tempfile.mkdtemp() and atomically rename it only after validation succeeds.
  • Verify that the cache directory and all consumed files are owned by the expected user and are not writable by other users.
  • Reject symlinks and special files throughout cache validation and archive extraction.
  • Derive cache identifiers from a collision-resistant digest of the complete package identifier and exact version.
  • Pin package versions and verify the archive against an expected integrity digest before extraction.
  • Store and validate a manifest recording package name, version, archive digest, extraction status, and tool version.
  • Extract archives with a library that validates every member path and rejects path traversal, links, device files, and unexpected ownership metadata.
  • Avoid treating the presence of any arbitrary non-archive file as proof that a cache entry is valid.
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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (28)

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 · SKILL.md (reported line 102)May include surrounding context.

md
<mcp-server-name>/
  SKILL.md
  config.json            # public config (safe to commit)
  secrets.json           # secrets (gitignored, never commit)
  secrets.json.example   # secrets template (safe to commit)
  .gitignore
  helpers/               (create on demand, do not pre-create empty)

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 · SKILL.md (reported line 103)May include surrounding context.

md
<mcp-server-name>/
  SKILL.md
  config.json            # public config (safe to commit)
  secrets.json           # secrets (gitignored, never commit)
  secrets.json.example   # secrets template (safe to commit)
  .gitignore
  helpers/               (create on demand, do not pre-create empty)

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 · SKILL.md (reported line 136)May include surrounding context.

md
<mcp-server-name>/
  SKILL.md
  config.json            # public config (safe to commit)
  secrets.json           # secrets (gitignored, never commit)
  secrets.json.example   # secrets template (safe to commit)
  .gitignore
  helpers/               (create on demand, do not pre-create empty)

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 · SKILL.md (reported line 143)May include surrounding context.

md
<mcp-server-name>/
  SKILL.md
  config.json            # public config (safe to commit)
  secrets.json           # secrets (gitignored, never commit)
  secrets.json.example   # secrets template (safe to commit)
  .gitignore
  helpers/               (create on demand, do not pre-create empty)

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 · SKILL.md (reported line 152)May include surrounding context.

md
<mcp-server-name>/
  SKILL.md
  config.json            # public config (safe to commit)
  secrets.json           # secrets (gitignored, never commit)
  secrets.json.example   # secrets template (safe to commit)
  .gitignore
  helpers/               (create on demand, do not pre-create empty)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

The prescribed read order prefers secrets.json over environment variables and normalizes plaintext secret storage on disk. While not overtly malicious, encouraging repeated reads of local plaintext secrets increases exposure through filesystem compromise, accidental backups, or permissive file permissions.

Content

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

secrets.json

text

**Read order for scripts:** `secrets.json` → environment variable (e.g. `X_API_TOKEN`). If both are empty, error and prompt user to copy the example file and fill it in.

Important: `config.json` and `secrets.json` are read on every tool call (not cached at startup).

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Reading config.json and secrets.json on every tool call increases the number of secret access events and the chance of accidental disclosure through logs, tracing, or race conditions. The risk is contextual rather than inherently malicious, but it expands the exposure surface for stored credentials.

Content

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

md
**Read order for scripts:** `secrets.json` → environment variable (e.g. `X_API_TOKEN`). If both are empty, error and prompt user to copy the example file and fill it in.

Important: `config.json` and `secrets.json` are read on every tool call (not cached at startup).

**Language:** Generate all text content in the language specified in Step 1. Default is English.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill requests broad capabilities (file writes, MCP interaction, and shell execution) but declares no explicit tool scope or permission boundaries. In practice, this increases the blast radius because the agent may execute package installs, shell commands, file creation, and registration steps without an allowlist constraining behavior.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill claims it does not execute MCP tool calls or business logic, but later instructs the agent to execute inferred commands against the target service/API. That mismatch is dangerous because users may consent under a lower-risk mental model while the skill actually performs live operations against external systems.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill's stated purpose is conversion, but it includes package installation capability that changes the host environment. This broadens the operational scope from analysis/generation into system modification, increasing the chance of unintended or unsafe changes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill directs package installation and shell execution without an upfront warning that it will modify the system. Users may trigger the skill expecting analysis/generation only, not environment changes such as installing Python packages.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Executing inferred network or CLI commands against target systems goes beyond passive conversion and introduces the risk of unauthorized interaction, data exposure, or unintended side effects. Even 'read-only' inference can be wrong, causing requests to the wrong endpoint, leaking tokens, or hitting sensitive systems.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill instructs file and directory creation in the user's working directory without clear advance notice. This can overwrite existing content, create sensitive files, or leave artifacts users did not intend to generate.

Content

No source excerpt is available for this finding.

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 123)May include surrounding context.


text

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Automatic registration modifies the agent's global or local configuration and may create symlinks in trusted skill directories without a clear upfront warning. This can persist new behavior in future agent sessions and effectively installs code into the agent environment.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding

Using npx skills without pinning a version allows execution of whatever package version is currently resolved from the registry. That creates a supply-chain risk where a malicious or compromised upstream release could run arbitrary code during registration.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding

This invocation again relies on unpinned npx skills, exposing the host to upstream package substitution or malicious updates. Because the command is part of an automated registration flow, users may not notice that third-party code is being fetched and executed.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding

Checking availability with unpinned npx skills --version still triggers dependence on an unpinned package ecosystem. Even probe steps can normalize unsafe package execution patterns in agent workflows.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding

This duplicate occurrence at the same line carries the same risk: unpinned package execution through npx skills. In the context of agent setup, that can lead to arbitrary code execution on the user's machine if the package source is compromised.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Natural-language strings in the module docstring and help text are presented exclusively in Chinese, with no alternative language option or documented locale constraint. This creates a language policy issue because users are implicitly required to understand a specific language to use the skill safely and correctly.

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.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
89% confidence
Finding

The code invokes an external package manager on attacker-influenced input (package derived from the supplied command). Although subprocess.run is used without a shell, which avoids shell injection, npm pack still performs network/package-resolution activity against an untrusted package name and can pull unexpected content into a writable cache directory. In this skill's context, converting arbitrary MCP servers means users are likely to inspect untrusted third-party packages, so this behavior expands supply-chain risk and local exposure.

Content

Scanner excerpt · mcp_inspector.py (reported line 63)May include surrounding context.

python
try:
        # npm pack 下载 tarball
        result = subprocess.run(
            ['npm', 'pack', package],
            capture_output=True, text=True, cwd=str(cache_dir), timeout=60
        )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
92% confidence
Finding

The script extracts a downloaded tarball from an untrusted npm package using tar xzf without any validation of archive contents. Malicious tarballs can contain path traversal entries, symlinks, or other crafted metadata that may overwrite files, plant links, or poison the cache directory during extraction. Because this skill is specifically designed to download and inspect arbitrary MCP server packages, the surrounding context makes unsafe archive extraction materially more dangerous.

Content

Scanner excerpt · mcp_inspector.py (reported line 75)May include surrounding context.

python
return None

        # 解压(--strip-components=1 去掉 package/ 前缀)
        extract_result = subprocess.run(
            ['tar', 'xzf', str(tarball), '--strip-components=1'],
            capture_output=True, cwd=str(cache_dir), timeout=30
        )

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.