Back to skill

Security audit

android build tool

Security checks for vulnerabilities and agentic risk

Overview

This skill should be reviewed carefully because it automatically downloads and runs an unverified external executable when invoked.

Install only if you trust the publisher and the GitHub release binary as much as local code execution on your machine. Prefer a version that vendors auditable source or verifies a pinned checksum/signature, uses subprocess argument arrays instead of os.system, and asks before downloading, changing environment variables, or running builds.

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
pi_claw.py:20
Finding
Automatic Download and Execution of an Unverified Native Binary<![CDATA[ ## Vulnerability Details **File Location**: `pi_claw.py:20-52` **Vulnerability Type**: Unverified remote payload retrieval and execution **Risk Level**: Critical ### Vulnerable Code ```python def download_pi(): """Download the pi executable""" system = platform.system() pi_path = get_pi_path() if system == "Windows": url = "https://github.com/noah-smith-max/pi_public/releases/download/r0.0.1/pi.exe" elif system == "Darwin": url = "https://github.com/noah-smith-max/pi_public/releases/download/r0.0.1/pi" else: print("Error: Linux is not supported yet.") sys.exit(1) print(f"Downloading pi from {url}...") urllib.request.urlretrieve(url, pi_path) if system != "Windows": os.chmod(pi_path, 0o755) print("Download completed successfully.") def main(): """Main function""" pi_path = get_pi_path() # Check if pi exists if not os.path.exists(pi_path): download_pi() # Build command arguments args = [pi_path] + sys.argv[1:] # Execute pi command try: result = os.system(' '.join(args)) sys.exit(result) except Exception as e: print(f"Error executing pi: {e}") sys.exit(1) ``` The same release assets are advertised in `SKILL.md:67-72`: ```markdown ## Download - Windows: https://github.com/noah-smith-max/pi_public/releases/download/r0.0.1/pi.exe - macOS: https://github.com/noah-smith-max/pi_public/releases/download/r0.0.1/pi ``` ### Technical Analysis The wrapper does not implement the declared Android and Flutter SDK management functionality itself. Instead, it delegates that functionality to a native executable retrieved from a personal GitHub release. When the expected local binary is absent, `urllib.request.urlretrieve` downloads the platform-specific artifact directly into the Skill directory. On macOS, the wrapper then grants executable permissions with `os.chmod(p ...[truncated 2394 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the opaque native executable with auditable source code included in the Skill or distribute it through a suitably controlled and authenticated package channel. 2. Publish a separate, immutable SHA-256 digest for each supported platform and embed the expected digest in the reviewed wrapper. 3. Download to a temporary file, calculate its digest, and fail closed before moving or executing it if the digest differs. 4. Apply code signing and verify the signature and expected publisher identity before execution: - Use Authenticode verification on Windows. - Use Apple code-signing and notarization verification on macOS. 5. Require explicit user confirmation that identifies the source, destination, version, and integrity value before downloading or executing the artifact. 6. Avoid relying only on a versioned URL as an integrity guarantee. 7. Use atomic file replacement and restrictive file permissions to reduce local replacement and partial-download risks. 8. Separate download, verification, and execution into distinct steps, with verification mandatory before execution. 9. Document the binary's source, build process, requested permissions, and expected network and filesystem behavior. 10. Run the tool with the least-privileged account practical for project setup and avoid administrative execution unless a specific operation requires it. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
pi_claw.py:47
Finding
Shell Command Injection Through Unquoted Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `pi_claw.py:47-52` **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```python # Build command arguments args = [pi_path] + sys.argv[1:] # Execute pi command try: result = os.system(' '.join(args)) sys.exit(result) except Exception as e: print(f"Error executing pi: {e}") sys.exit(1) ``` ### Technical Analysis The wrapper constructs a command by joining the executable path and all user-controlled command-line arguments with spaces. It then passes the resulting string to `os.system`, which executes it through the operating-system command shell. No shell quoting or escaping is applied. Arguments containing shell metacharacters can therefore be interpreted as additional shell syntax rather than as literal arguments to the `pi` executable. The exact metacharacters depend on the platform, but examples include command separators, redirection operators, pipes, and command-substitution syntax. The executable path can also be parsed incorrectly if the Skill directory contains spaces or shell metacharacters. This creates both reliability problems and an additional injection surface when an attacker can influence the installation path. Validation alone is not an adequate primary fix because platform-specific shell parsing is complex. The shell should not be involved in launching this executable. ### Attack Path 1. An attacker causes the wrapper to be invoked with a project path or another argument containing shell control syntax. 2. The value is placed directly into `sys.argv`. 3. The wrapper combines all elements using `' '.join(args)` without quoting or escaping them. 4. `os.system` sends the combined string to the platform shell. 5. The shell interprets attacker-controlled metacharacters as commands, pipes, or redirections. 6. The injected command runs with the same privileges and environment as `pi_claw.py`. A realistic exposure exists when project pat ...[truncated 951 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Launch the executable directly with an argument array instead of constructing a shell command: ```python import subprocess try: result = subprocess.run( [pi_path, *sys.argv[1:]], shell=False, check=False, ) sys.exit(result.returncode) except OSError as e: print(f"Error executing pi: {e}", file=sys.stderr) sys.exit(1) ``` Additional hardening should include: 1. Keep `shell=False` and do not convert the argument list back into a command string. 2. Validate supported subcommands and reject unknown command forms where practical. 3. Resolve and validate project paths before forwarding them, while preserving them as individual arguments. 4. Confirm that `pi_path` is the expected regular file and not an attacker-controlled symbolic link. 5. Do not attempt to solve this issue solely through manual shell escaping, because escaping requirements differ between Windows and macOS. 6. Add tests using paths and arguments containing spaces, quotes, command separators, pipes, and redirection characters to verify that they remain literal arguments. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared purpose is Android SDK setup and project building, but the behavior indicates downloading and executing an external binary wrapper without clear evidence of the promised functionality. This mismatch is dangerous because it can conceal arbitrary code execution behind a benign-looking description, making users more likely to approve risky actions they do not understand.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The skill claims to manage Android SDKs, but the implementation downloads and runs an unrelated binary named 'pi' from a GitHub release. This mismatch between declared purpose and actual behavior is a strong supply-chain and trust violation because users may invoke the skill expecting SDK setup while unknowingly executing unrelated code.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The file downloads an external executable and immediately later executes it, which grants arbitrary code execution to whatever content is hosted at the release URL. That capability is not justified by the stated skill purpose, making the behavior especially suspicious and dangerous in an agent context where users may not expect binary execution.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Content
# Execute pi command
    try:
        result = os.system(' '.join(args))
        sys.exit(result)
    except Exception as e:
        print(f"Error executing pi: {e}")
Confidence
99% confidence
Finding
The code builds a shell command by joining the downloaded binary path with user-controlled command-line arguments and passes it to os.system(). This enables shell metacharacter injection and executes through the shell, compounding the risk because the target executable is itself downloaded at runtime from the internet.

Lp3

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding
The skill advertises behavior that inherently requires network access and shell execution, but it does not declare any explicit tool scope or permissions boundaries. This is dangerous because users and reviewers cannot easily tell what external actions the skill may perform, reducing transparency and increasing the chance of unexpected downloads or command execution.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The invocation description is broad enough to trigger on many ordinary project or build-related requests, increasing the chance that the skill is invoked in contexts where users did not specifically request downloads, environment changes, or builds. Because the skill can modify the system and run external code, over-broad activation materially raises the risk of unintended execution.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill describes downloading software, configuring environment variables, and creating shortcut commands, but does not prominently warn users that it will make system-level changes. This is dangerous because users may invoke it expecting informational help, while it can alter their development environment in persistent ways.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The code silently downloads an executable into the skill directory with only a generic status message and no explicit consent, warning, or integrity verification. This increases the chance of unnoticed installation of untrusted code and reduces the user's opportunity to make an informed trust decision.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill executes the binary without a specific warning that a subprocess or external program will be launched. In this context, that is dangerous because the binary was obtained dynamically and users of an Android SDK management skill would not reasonably expect unrelated executable code to run.

Missing User Warnings

Low
Confidence
80% confidence
Finding
The build functionality is presented without warning that building a project may execute project-defined scripts, toolchains, or plugins and may modify build artifacts. In the context of untrusted repositories, invoking a build can trigger arbitrary commands embedded in the project's build configuration.

Static analysis

No suspicious patterns detected.