Back to skill

Security audit

CLI Anything Wrapper

Security checks for vulnerabilities and agentic risk

Overview

The skill is a plausible CLI wrapper, but installation and fallback execution can run unverified third-party code from a mutable GitHub checkout.

Install only if you trust CLI-Anything and are comfortable letting this wrapper run third-party harness code on your machine. Prefer a manually reviewed, pinned CLI-Anything checkout, avoid --install until it verifies exact revisions, and use dry-run before invoking apps that can alter files or application state.

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/run.py:244
Finding
Unpinned Remote Repository and Submodule Code Is Installed and Executed## Vulnerability Details **File Location**: `scripts/run.py:244-253` **Vulnerability Type**: Unverified remote payload retrieval and supply-chain exposure **Risk Level**: High **Complete Code Snippet**: ```python cmds = [ f"git clone --recursive https://github.com/HKUDS/CLI-Anything {self.cli_path}", f"cd {self.cli_path} && ./setup.sh 2>/dev/null || pip install -e . 2>/dev/null || echo 'setup.sh 不存在,尝试手动安装'", ] for cmd in cmds: print(f"\n$ {cmd}") result = subprocess.run(cmd, shell=True, capture_output=True, text=True) if result.returncode != 0 and "already exists" not in result.stderr: print(f"⚠️ 命令可能失败: {result.stderr[:200]}") ``` ### Technical Analysis The `--install` operation clones the mutable default branch of an external repository, including recursive submodules, and immediately executes code from the resulting checkout. Neither the main repository nor its submodules are pinned to reviewed commits. The implementation also performs no cryptographic hash, release-signature, or provenance verification before invoking `setup.sh` or editable package installation logic. Consequently, the effective code executed by this skill can change after the skill itself has been reviewed. This creates a remote payload execution and supply-chain trust boundary: control of the upstream repository, its default branch, or any recursively cloned submodule is sufficient to alter locally executed installation code. The use of `shell=True` is unnecessary and enlarges the command execution surface. The destination currently derives from `Path.home()` rather than direct user input, so no standalone shell-injection path through that variable was established during this audit; the confirmed issue is execution of mutable, unverified remote code. ### Attack Path 1. An attacker compromises the upstream repository, a maintainer account, the default branch, or one of its recursive submodules. 2. The attacke ...[truncated 1006 chars]
Remediation
## Remediation Suggestions - Pin the main repository to an explicitly reviewed commit hash or signed release tag. - Pin and verify every submodule commit rather than trusting mutable branch state. - Verify downloaded content against hardcoded expected hashes or validated cryptographic signatures before executing it. - Prefer distributing a reviewed, versioned dependency artifact through a trusted package channel. - Present the exact revision and planned commands and require explicit user confirmation before installation. - Replace `shell=True` command strings with argument arrays and separate subprocess calls for cloning and installation. - Do not suppress installer error output, because doing so obscures security-relevant failures. - Run installation in a sandbox or isolated environment with minimal filesystem, credential, and network access.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run.py:207
Finding
Arbitrary Harness Script May Be Selected as a Fallback Entry Point## Vulnerability Details **File Location**: `scripts/run.py:207-231` **Vulnerability Type**: Unsafe executable discovery and execution **Risk Level**: Medium **Complete Code Snippet**: ```python # 检查 CLI 脚本是否存在 cli_script = harness_path / "cli-anything" if not cli_script.exists(): # 尝试找其他可执行文件 candidates = list(harness_path.glob("*.py")) + list(harness_path.glob("*.sh")) if candidates: cli_script = candidates[0] else: print(f"❌ 未找到可执行脚本") print(f" 请检查 {harness_path} 内容") return 1 # 执行 print(f"\n▶️ 执行: {cli_script} {args}") try: result = subprocess.run( [str(cli_script)] + (args.split() if args else []), cwd=harness_path, capture_output=True, text=True, timeout=300 ) ``` ### Technical Analysis When the expected `cli-anything` entry point is absent, the wrapper enumerates all top-level `.py` and `.sh` files and executes the first candidate. It does not enforce an approved filename, verify a digest or signature, confirm ownership and permissions, ensure that the resolved path remains within the expected harness directory, or otherwise establish that the selected file is a legitimate entry point. File enumeration order is not a security boundary and should not determine which program receives execution. The risk is amplified because harness content is obtained from an external repository and may also be writable by processes operating under the same account. The subprocess call uses an argument vector rather than a shell, so shell metacharacters in `args` do not directly produce shell command injection at this call site. The vulnerability instead concerns the identity and provenance of the executable itself. ### Attack Path 1. An attacker gains control of a harness checkout through an upstream supply-chain compromise or write access to the local harness directory. 2. The attacker removes or om ...[truncated 882 chars]
Remediation
## Remediation Suggestions - Remove generic `.py` and `.sh` fallback discovery. - Define an exact, per-application allowlist of expected entry-point paths. - Reject the operation if the approved entry point is missing instead of guessing another executable. - Resolve the selected path and verify that it remains under the intended harness directory. - Verify the entry point against a pinned digest or trusted signature before execution. - Check that the file is a regular file, is not a symlink, has acceptable ownership, and is not writable by untrusted users. - Execute harnesses in a restricted sandbox with only the filesystem and network permissions required by the target application. - Add tests proving that unexpected scripts are rejected when the legitimate entry point is absent.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
声明描述的是一个供 OpenClaw 调用任意软件 CLI 功能的包装器能力;但提供的代码片段仅是 tests/test_wrapper.py 测试文件。它通过导入 run 模块、构造测试对象、mock Path.exists/print/sys.argv,并运行若干断言来验证包装器相关组件是否存在和表现是否符合预期。该片段没有实现实际的 CLI 转发、命令执行或对外提供包装能力,因此其主要目的与声明不一致。虽然测试代码与该项目主题相关,但就该代码片段本身而言,描述不能准确代表其实际行为。

Tool Parameter Abuse

High
Category
Tool Misuse
Content
for cmd in cmds:
            print(f"\n$ {cmd}")
            result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
            if result.returncode != 0 and "already exists" not in result.stderr:
                print(f"⚠️  命令可能失败: {result.stderr[:200]}")
Confidence
99% confidence
Finding
This is a true tool-parameter abuse issue because the skill constructs shell commands that combine trusted program names with path data and executes them via the shell. In the context of an agent skill intended to install and run arbitrary CLI tooling, this is more dangerous than usual because it expands the execution surface and can turn environmental/path manipulation into arbitrary command execution.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill exposes shell-capable behavior for invoking external CLI tools but does not declare any tool scope or permission boundaries. In this context, the wrapper is explicitly designed to pass user-supplied arguments to third-party software, so the lack of permissions metadata increases the chance of overbroad execution, unsafe invocation, and poor policy enforcement by the host agent.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation encourages passing arbitrary user-controlled arguments to external applications without warning that those applications may write files, execute scripts, access plugins, consume network resources, or otherwise alter system state. In a wrapper specifically intended to drive many third-party CLIs, omission of this warning materially increases the risk of unsafe use and social engineering through seemingly harmless commands.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This markdown file contains end-user instructions exclusively in Chinese, including the title and all operational guidance. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is clearly documented and justified, which is not present here.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
This code file contains natural-language descriptions in Chinese, including the module docstring and most user-facing CLI messages, while the file does not offer any language or locale selection. Under the policy for natural-language violations, forcing a specific language without user opt-in is in scope.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# 执行
        print(f"\n▶️  执行: {cli_script} {args}")
        try:
            result = subprocess.run(
                [str(cli_script)] + (args.split() if args else []),
                cwd=harness_path,
                capture_output=True,
Confidence
95% confidence
Finding
This code executes a harness script selected from a locally cloned external repository and passes through user-controlled arguments with minimal validation. Although it avoids shell=True here, the skill’s purpose is to let an agent invoke arbitrary software CLIs, so an attacker who can influence the cloned harness contents or the provided arguments can cause execution of unintended or dangerous commands through the harness itself.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
for cmd in cmds:
            print(f"\n$ {cmd}")
            result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
            if result.returncode != 0 and "already exists" not in result.stderr:
                print(f"⚠️  命令可能失败: {result.stderr[:200]}")
Confidence
99% confidence
Finding
This subprocess call uses shell=True to execute composed command strings, which is dangerous because shell metacharacters in interpolated values can alter the command. Here, self.cli_path is embedded directly into shell commands; if the home directory or path contains shell-special characters, this can become command injection during installation.

Natural-Language Policy Violations

Low
Confidence
85% confidence
Finding
The user-facing description and instructions are written entirely in Chinese, with no indication that this skill is intentionally region-specific or that other languages are available. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
This shell script’s natural-language content is presented entirely in Chinese in comments and echoed messages, with no indication that the skill is intended only for a Chinese-speaking audience or that users can choose another language. That can violate language/locale policy requirements when skills should not force a specific language without opt-in.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
This Python file contains natural-language strings in Chinese, including the module docstring title, with no indication that language selection is optional or region-specific. Under the policy, forcing a specific language without user opt-in can be a locale-policy violation.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Content
if method_name.startswith('test_'):
                total += 1
                try:
                    getattr(instance, method_name)()
                    passed += 1
                    print(f"  ✅ {method_name}")
                except Exception as e:
Confidence
50% confidence
Finding
Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Static analysis

No suspicious patterns detected.