Back to skill

Security audit

skill-python-env

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent Python environment helper, but it automatically runs live remote installer code and can delete paths derived from an unvalidated version argument.

Review before installing. This skill should only be used if you trust its callers and are comfortable with automatic uv installation from live remote scripts. Safer use would require uv to be preinstalled, validate python_version to plain versions such as 3.11, restrict packages, and avoid recursive deletion outside verified environment directories.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/ensure_python_env.sh:84
Finding

Unverified Remote Installer Download and Execution

Content
View full analysis
/dev/null; then log_info "使用 PowerShell 安装 uv..." powershell.exe -ExecutionPolicy ByPass -Command \ "irm https://astral.sh/uv/install.ps1 | iex" else log_error "未找到 powershell.exe,请手动安装 uv:" log_error " https://docs.astral.sh/uv/getting-started/installation/" exit 1 fi export PATH="$USERPROFILE/.local/bin:$HOME/.local/bin:$PATH" else if command -v curl &>/dev/null; then log_info "使用 curl 安装 uv..." curl -LsSf https://astral.sh/uv/install.sh | sh elif command -v wget &>/dev/null; then log_info "使用 wget 安装 uv..." wget -qO- https://astral.sh/uv/install.sh | sh ``` The Python implementation performs the same operation: ```python if is_windows(): ps = shutil.which("powershell.exe") or shutil.which("powershell") if not ps: log_error("未找到 PowerShell,请手动安装 uv:") log_error(" https://docs.astral.sh/uv/getting-started/installation/") sys.exit(1) log_info("使用 PowerShell 安装 uv...") result = subprocess.run( [ps, "-ExecutionPolicy", "ByPass", "-Command", "irm https://astral.sh/uv/install.ps1 | iex"], check=False, ) if result.returncode != 0: log_error("PowerShell 安装 uv 失败,请手动安装:") log_error(" https://docs.astral.sh/uv/getting-started/installation/") sys.exit(1) else: curl = shutil.which("curl") wget = shutil.which("wget") if curl: log_info("使用 curl 安装 uv...") proc = subprocess.run([curl, "-LsSf", "https://astral.sh/uv/install.sh"], stdout=subprocess.PIPE, check=True) subproc ...[truncated 2945 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/ensure_python_env.sh:39
Finding

Unvalidated Environment Version Permits Path Traversal and Recursive Deletion

Content
View full analysis
None: activate = get_activate_path(env_dir) if env_dir.exists() and activate.exists(): log_ok(f"Python {python_version} 环境已存在:{env_dir}") return if env_dir.exists() and not activate.exists(): log_warn(f"目录 {env_dir} 存在但环境不完整,重新创建...") shutil.rmtree(env_dir) ``` ```python python_version: str = args.python_version env_dir = Path.home() / ".python_env" / python_version ``` ### Technical Analysis The `python_version` argument is treated both as a Python version selector and as a filesystem path component. Neither implementation restricts it to a valid version syntax such as `3.11` or verifies that the resolved target remains below `~/.python_env`. A value containing `..` and path separators can traverse out of the intended base directory after filesystem path normalization. In Python, an absolute final path component can also replace the preceding `P ...[truncated 2425 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (18)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

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

Q: 想重置某个版本的环境 删除目录后重新调用即可自动重建:

bash
rm -rf ~/.python_env/3.11
bash ensure_python_env.sh 3.11

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

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

Q: 想重置某个版本的环境 删除目录后重新调用即可自动重建:

bash
rm -rf ~/.python_env/3.11
bash ensure_python_env.sh 3.11

Chaining Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

Piping a network response directly into sh is a classic arbitrary-code-execution sink. Because this script is an internal utility used by other skills, the dangerous behavior can be chained indirectly, making it easier to trigger execution in contexts where the operator may not realize remote code will run.

Content

Scanner excerpt · scripts/ensure_python_env.sh (reported line 92)May include surrounding context.

sh
else
        if command -v curl &>/dev/null; then
            log_info "使用 curl 安装 uv..."
            curl -LsSf https://astral.sh/uv/install.sh | sh
        elif command -v wget &>/dev/null; then
            log_info "使用 wget 安装 uv..."
            wget -qO- https://astral.sh/uv/install.sh | sh

Chaining Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

This is the same high-risk chaining pattern in the wget fallback: untrusted remote content is streamed directly into the shell. If an attacker can influence the download source, DNS, TLS trust, or hosting account, they gain immediate code execution under the current user.

Content

Scanner excerpt · scripts/ensure_python_env.sh (reported line 95)May include surrounding context.

sh
curl -LsSf https://astral.sh/uv/install.sh | sh
        elif command -v wget &>/dev/null; then
            log_info "使用 wget 安装 uv..."
            wget -qO- https://astral.sh/uv/install.sh | sh
        else
            log_error "未找到 curl 或 wget,请手动安装 uv:"
            log_error "  https://docs.astral.sh/uv/getting-started/installation/"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill documentation describes shell execution, environment manipulation, and network-based installation of tooling, but it does not declare any explicit tool scope or permissions. For an internal reusable skill that other skills invoke automatically, this increases the chance of unintended shell/network use without policy gating or informed review.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

The script downloads and immediately executes a remote PowerShell installation command (irm ... | iex) with no pinning, signature verification, or out-of-band integrity check. If the remote endpoint, network path, or installation source is compromised, this results in arbitrary code execution on the host.

Content

Scanner excerpt · scripts/ensure_python_env.py (reported line 103)May include surrounding context.

python
log_error("  https://docs.astral.sh/uv/getting-started/installation/")
            sys.exit(1)
        log_info("使用 PowerShell 安装 uv...")
        result = subprocess.run(
            [ps, "-ExecutionPolicy", "ByPass", "-Command",
             "irm https://astral.sh/uv/install.ps1 | iex"],
            check=False,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

This downloads a remote shell installer script over the network and prepares it for immediate execution. Even though the fetch itself is not the execution step, it is part of an unsafe bootstrap pattern that trusts live remote script content without integrity validation.

Content

Scanner excerpt · scripts/ensure_python_env.py (reported line 117)May include surrounding context.

python
wget = shutil.which("wget")
        if curl:
            log_info("使用 curl 安装 uv...")
            proc = subprocess.run([curl, "-LsSf", "https://astral.sh/uv/install.sh"],
                                  stdout=subprocess.PIPE, check=True)
            subprocess.run(["sh"], input=proc.stdout, check=True)
        elif wget:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
100% confidence
Finding

This executes the previously downloaded installer script by piping its contents into sh. That is a direct remote-code-execution pattern with no integrity verification, making compromise of the source or transport immediately exploitable.

Content

Scanner excerpt · scripts/ensure_python_env.py (reported line 119)May include surrounding context.

python
log_info("使用 curl 安装 uv...")
            proc = subprocess.run([curl, "-LsSf", "https://astral.sh/uv/install.sh"],
                                  stdout=subprocess.PIPE, check=True)
            subprocess.run(["sh"], input=proc.stdout, check=True)
        elif wget:
            log_info("使用 wget 安装 uv...")
            proc = subprocess.run([wget, "-qO-", "https://astral.sh/uv/install.sh"],

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

Like the curl-based path, this fetches a remote installer script from the network without version pinning or integrity validation. It is part of an unsafe bootstrap chain that can be subverted into arbitrary code execution if the fetched content is malicious.

Content

Scanner excerpt · scripts/ensure_python_env.py (reported line 122)May include surrounding context.

python
subprocess.run(["sh"], input=proc.stdout, check=True)
        elif wget:
            log_info("使用 wget 安装 uv...")
            proc = subprocess.run([wget, "-qO-", "https://astral.sh/uv/install.sh"],
                                  stdout=subprocess.PIPE, check=True)
            subprocess.run(["sh"], input=proc.stdout, check=True)
        else:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
100% confidence
Finding

This executes the network-fetched installer content by feeding it directly to sh, creating a straightforward arbitrary code execution path. Any compromise of the download source, TLS interception environment, or supply chain would fully compromise the machine running the skill.

Content

Scanner excerpt · scripts/ensure_python_env.py (reported line 124)May include surrounding context.

python
log_info("使用 wget 安装 uv...")
            proc = subprocess.run([wget, "-qO-", "https://astral.sh/uv/install.sh"],
                                  stdout=subprocess.PIPE, check=True)
            subprocess.run(["sh"], input=proc.stdout, check=True)
        else:
            log_error("未找到 curl 或 wget,请手动安装 uv:")
            log_error("  https://docs.astral.sh/uv/getting-started/installation/")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/ensure_python_env.py (reported line 143)May include surrounding context.

python
log_error("  https://docs.astral.sh/uv/getting-started/installation/")
        sys.exit(1)

    version = subprocess.check_output([uv_path, "--version"], text=True).strip()
    log_ok(f"uv 安装成功:{version}")
    if is_windows():
        log_warn(r"请将 %USERPROFILE%\.local\bin 加入系统 PATH 以永久生效")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/ensure_python_env.py (reported line 156)May include surrounding context.

python
log_error("  https://docs.astral.sh/uv/getting-started/installation/")
        sys.exit(1)

    version = subprocess.check_output([uv_path, "--version"], text=True).strip()
    log_ok(f"uv 安装成功:{version}")
    if is_windows():
        log_warn(r"请将 %USERPROFILE%\.local\bin 加入系统 PATH 以永久生效")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/ensure_python_env.py (reported line 178)May include surrounding context.

python
log_info(f"创建 Python {python_version} 虚拟环境:{env_dir}")
    env_dir.parent.mkdir(parents=True, exist_ok=True)

    result = subprocess.run(
        [uv_path, "venv", str(env_dir), "--python", python_version],
        check=False,
    )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

This script accepts arbitrary package names from callers and installs them into a shared environment reused by multiple skills. That creates a supply-chain and cross-skill trust-boundary issue: one caller can poison the shared environment with malicious or incompatible packages, affecting later executions of other skills that trust the same ~/.python_env/<version> environment.

Content

Scanner excerpt · scripts/ensure_python_env.py (reported line 194)May include surrounding context.

python
if not packages:
        return
    log_info(f"安装依赖包:{' '.join(packages)}")
    result = subprocess.run(
        [uv_path, "pip", "install", "--python", str(env_dir), *packages],
        check=False,
    )

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script automatically downloads and executes a remote installer when uv is missing, without requiring explicit confirmation or performing integrity verification. In an internal shared skill that may be invoked transitively by other skills, this creates a supply-chain risk: a compromised upstream host, TLS-intercepting environment, or unexpected installer change would result in arbitrary code execution on the host.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

If the target environment directory exists but is deemed incomplete, the script removes it with rm -rf. The current log message notes recreation, but it does not clearly warn that the existing directory and its contents will be deleted, which is a destructive operation affecting user data under ~/.python_env.

Content

No source excerpt is available for this finding.

External Script Fetching

Low
Category
Supply Chain
Confidence
96% confidence
Finding

This line fetches an external installation script over the network and immediately executes it via the shell. That pattern delegates full trust to a remote endpoint at runtime and exposes the host to arbitrary code execution if the source or delivery path is compromised.

Content

Scanner excerpt · scripts/ensure_python_env.sh (reported line 90)May include surrounding context.

sh
fi
        export PATH="$USERPROFILE/.local/bin:$HOME/.local/bin:$PATH"
    else
        if command -v curl &>/dev/null; then
            log_info "使用 curl 安装 uv..."
            curl -LsSf https://astral.sh/uv/install.sh | sh
        elif command -v wget &>/dev/null; then

External Script Fetching

Low
Category
Supply Chain
Confidence
96% confidence
Finding

This wget branch has the same external-script-fetching risk as the curl branch: it retrieves code from a remote server and passes it directly to sh. In a shared internal helper skill, callers may trigger this behavior implicitly, increasing the blast radius of any upstream compromise.

Content

Scanner excerpt · scripts/ensure_python_env.sh (reported line 93)May include surrounding context.

sh
if command -v curl &>/dev/null; then
            log_info "使用 curl 安装 uv..."
            curl -LsSf https://astral.sh/uv/install.sh | sh
        elif command -v wget &>/dev/null; then
            log_info "使用 wget 安装 uv..."
            wget -qO- https://astral.sh/uv/install.sh | sh
        else

Static analysis

No suspicious patterns detected.