Back to skill

Security audit

cli2skill

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent purpose, but it can turn untrusted CLI or MCP output into persistent agent instructions with broad shell authority and limited safety checks.

Review generated skill files before placing them in an active agent skill directory. Avoid running this against untrusted CLIs or MCP servers, avoid unpinned npx packages, use a minimal environment, and prefer a staging output directory instead of ~/.claude/skills/.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (4)

T01 · Skill Instruction Hijacking

Error
Location
cli2skill/mcp2skill.py:92
Finding

Untrusted CLI and MCP Metadata Is Persisted as Agent Instructions

Content
View full analysis
str: """Run `executable --help` and capture stdout+stderr.""" # Support multi-word executables like "python script.py" cmd = executable.split() + (args or []) + ["--help"] try: result = subprocess.run( cmd, capture_output=True, text=True, timeout=10, ) return result.stdout or result.stderr ``` `cli2skill/parser.py:65-71`: ```python desc_lines = [] for line in lines: lower = line.strip().lower() if any(lower.startswith(h) for h in section_headers): break if line.strip(): desc_lines.append(line.strip()) meta.description = " ".join(desc_lines[:2]) # Keep first 2 lines max ``` `cli2skill/generator.py:11-25`: ```python # Frontmatter lines.append("---") lines.append(f"name: {meta.name}") desc = meta.description[:100] if meta.description else f"Agent skill for {meta.name} CLI" lines.append(f"description: {desc}") lines.append("user-invocable: false") lines.append(f"allowed-tools: Bash({exe} *)") lines.append("---") lines.append("") # Header lines.append(f"# {meta.name}") lines.append("") if meta.description: lines.append(meta.description) lines.append("") ``` `cli2skill/mcp2skill.py:92-99`: ```python raw_tools = resp["result"].get("tools", []) for t in raw_tools: tools.append(McpTool( name=t.get("name", "unknown"), description=t.get("description", ""), ...[truncated 4002 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
cli2skill/mcp2skill.py:135
Finding

MCP-Generated Skills Receive Unrestricted Bash Authorization

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
cli2skill/main.py:37
Finding

Unsanitized Skill Names Allow Writes Outside the Selected Output Directory

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:41
Finding

Operational Instructions Recommend Unpinned npx Package Execution

Content
View full analysis
list[McpTool]: """Spawn an MCP server, handshake, extract tools, kill it.""" merged_env = {**os.environ, **(env or {})} ``` ### Technical Analysis The project's own Agent Skill instructs users and Agents to execute MCP packages through `npx` without an exact package version, integrity hash, lockfile, or publisher verification. `npx` may retrieve package contents from a registry and execute package lifecycle or entry-point code locally. The example `some-mcp-server` is an arbitrary placeholder, while `tavily-mcp` is also shown without a pinned version. Registry package ownership or contents can change after the Skill has been reviewed. A typo, dependency compromise, ownership transfer, or malicious newly published package can therefore change the effective code executed by the documented command. The spawned package also receives a merged environment containing the complete parent process environment plus supplied values. A malicious package can consequently inspect credentials and tokens already present in the Agent environment. ### Attack Path 1. A user or Agent follows the command in `SKILL.md`. 2. `npx` resolves an unpinned package from its configured r ...[truncated 931 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (14)

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

Referencing ~/.claude/settings.json directs the skill toward reading the agent's configuration directory, which may contain sensitive configuration, server definitions, tokens, or trust settings. In the context of a skill generator that can also write into ~/.claude/skills/, access to agent config is more dangerous because it enables discovery and transformation of trusted local agent configuration into new executable skill content.

Content

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

md
cli2skill mcp npx some-mcp-server --name my-mcp -o ~/.claude/skills/

# From Claude Code settings.json
cli2skill mcp --config ~/.claude/settings.json --server my-server --name my-mcp -o ~/.claude/skills/

# With env vars
cli2skill mcp npx tavily-mcp --name tavily --env API_KEY=xxx -o ~/.claude/skills/

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · assets/banner.svg (reported line 17)May include surrounding context.

text
</linearGradient>
  </defs>

  <!-- Background -->
  <rect width="1200" height="400" fill="url(#bg)" rx="12"/>

  <!-- Title -->

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
96% confidence
Finding

The subprocess environment is built by inheriting the entire parent os.environ and overlaying config values, which forwards all ambient credentials and sensitive context to the spawned MCP server. If the target server is malicious or compromised, it can read and exfiltrate tokens, cloud credentials, SSH-related variables, and other host secrets.

Content

Scanner excerpt · cli2skill/mcp2skill.py (reported line 33)May include surrounding context.

python
timeout: int = 30,
) -> list[McpTool]:
    """Spawn an MCP server, handshake, extract tools, kill it."""
    merged_env = {**os.environ, **(env or {})}

    # Build the JSON-RPC messages
    init_req = json.dumps({

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The generated skill always declares allowed-tools: Bash(*), granting unrestricted shell access regardless of the MCP server's original capability scope. This is a privilege-escalation design flaw because a narrowly scoped MCP toolset is transformed into a skill that can execute arbitrary shell commands on the agent host.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill documents shell execution, environment variable use, and writing generated skills into the agent's skills directory, but it does not declare any tool scope or restrictions. In an agent setting, this increases the chance of over-broad execution and unsafe file writes because the skill can be invoked with powerful capabilities without explicit boundaries.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

Using npx some-mcp-server without a pinned package version causes code to be fetched and executed at runtime from the package registry, which is a supply-chain risk. A malicious or compromised upstream release could execute arbitrary code during skill use.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

Using npx tavily-mcp without a pinned version has the same supply-chain exposure: the latest package version is implicitly trusted and executed. Because this example also passes environment variables, compromise of the package could expose secrets provided to the process.

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
90% confidence
Finding

The code launches an arbitrary external command as an MCP server, which creates a code-execution boundary crossing from configuration/CLI input into a subprocess. On Windows it enables shell=True, which increases risk because command interpretation may occur through the shell and unexpected metacharacter handling or path hijacking can execute unintended programs.

Content

Scanner excerpt · cli2skill/mcp2skill.py (reported line 61)May include surrounding context.

python
# On Windows, commands like npx/node need shell=True or .cmd suffix
    use_shell = sys.platform == "win32"
    proc = subprocess.Popen(
        command,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file directly executes the supplied MCP server command without any warning, trust check, or confirmation step. Because MCP servers are executable local programs, merely 'extracting tools' can run attacker-controlled code if the command or config is untrusted.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The function expands environment-variable references from configuration and later passes them into the spawned MCP server process. In practice this can expose secrets such as API keys or tokens to any server being inspected, exceeding the minimum data needed for tool schema extraction.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
92% confidence
Finding

This code executes an attacker-controlled executable string via subprocess.run after splitting it with executable.split(), which means the skill will launch arbitrary local programs whenever it is asked to inspect a CLI. Although shell=True is not used, this is still dangerous because the feature explicitly runs untrusted binaries or scripts and even supports multi-word commands like 'python script.py', enabling code execution in the host environment simply by supplying a crafted target CLI.

Content

Scanner excerpt · cli2skill/parser.py (reported line 46)May include surrounding context.

python
# Support multi-word executables like "python script.py"
    cmd = executable.split() + (args or []) + ["--help"]
    try:
        result = subprocess.run(
            cmd, capture_output=True, text=True, timeout=10,
        )
        return result.stdout or result.stderr

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This markdown file documents commands such as gh auth, gh api, gh secret, gh ssh-key, gh repo, and gh release, which can access credentials, transmit authenticated data, or modify GitHub resources. The skill description provides command summaries but no user-facing warning about privacy, credential use, or potentially impactful changes to repositories and account settings.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

SQP-3 applies to all file types and covers language or locale policy violations. This markdown article presents all user-facing instructional content only in Chinese, with no opt-in, alternative language, or explanation that the skill is intended exclusively for a Chinese-speaking audience.

Content

No source excerpt is available for this finding.