Back to skill

Security audit

Skill Safe Install

Security checks for vulnerabilities and agentic risk

Overview

This security installer is purpose-aligned, but its own installer script has unsafe command execution and bypass options that make it require review before use.

Install only if you understand that this tool will download skills, execute local ClawHub/curl/zip commands, and upload skill archives to ThreatBook. Avoid using --auto, --yes, --force, --no-vetter, or --no-scan for untrusted skills. Treat the current script as needing fixes before use in CI or with sensitive credentials, especially command argument handling, API-key handling, and scan coverage.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/safe-install.mjs:202
Finding

Shell Command Injection Through Unvalidated Skill Name

Content
View full analysis

Vulnerability Details

File Location: scripts/safe-install.mjs:135-143, 202, 251, 372, 576, 767
Vulnerability Type: OS command injection
Risk Level: High

Vulnerable Code

js
function execCommand(cmd, options = {}) {
  try {
    const result = execSync(cmd, {
      encoding: 'utf8',
      stdio: options.silent ? 'pipe' : 'inherit',
      ...options
    });
    return { success: true, output: result };

User-controlled skillName is subsequently interpolated into shell command strings:

js
const inspectResult = execCommand(`clawhub inspect "${skillName}"`, { silent: true });

const downloadResult = execCommand(
  `clawhub install "${skillName}" --dir "${tempDir}"`,
  { silent: true }
);

const result = execCommand(`clawhub search "${skillName}"`, { silent: true });

const downloadResult = execCommand(
  `clawhub install "${skillName}" --dir "${tempDir}"`,
  { silent: true }
);

const result = execCommand(`clawhub install "${skillName}"`);

Technical Analysis

skillName originates from command-line arguments and is inserted directly into command strings passed to execSync. String-based execSync execution invokes a shell, so shell metacharacters and command substitutions in the Skill name are interpreted by that shell.

Wrapping the input in double quotes is insufficient. An attacker can use an embedded quote to terminate the intended argument or use shell constructs that remain active inside double quotes, such as command substitution. No strict Skill-name validation is performed before the value reaches these command sinks.

The vulnerability is triggered during metadata inspection, temporary download, rating lookup, sandbox preparation, or final installation. Consequently, code execution can occur before the security checks have completed.

Attack Path

  1. An attacker convinces a user or automated workflow to invoke the installer with a crafted Sk ...[truncated 1040 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace string-based execSync calls with execFileSync or spawnSync and pass arguments as an array:

    js
    import { execFileSync } from 'child_process';
    
    const output = execFileSync(
      'clawhub',
      ['inspect', skillName],
      {
        encoding: 'utf8',
        stdio: 'pipe',
        shell: false
      }
    );
    
  2. Apply the same change to every clawhub, curl, and zip invocation. Do not construct shell commands by concatenating or interpolating variable input.

  3. Validate Skill identifiers using an allowlist appropriate to ClawHub naming rules. For example, only permit letters, digits, underscores, periods, hyphens, and an explicitly supported namespace separator.

  4. Reject control characters, whitespace, quotes, backticks, dollar signs, and shell metacharacters before invoking any external process.

  5. Add automated tests covering embedded quotes, command substitution, semicolons, newlines, and other shell-injection payload classes.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/safe-install.mjs:427
Finding

ThreatBook API Key Exposed Through Shell Command Arguments and Error Output

Content
View full analysis

Vulnerability Details

File Location: scripts/safe-install.mjs:427-436, 457-458
Vulnerability Type: Sensitive credential exposure and secondary command injection
Risk Level: Medium

Vulnerable Code

js
const curlCmd = `curl -s -X POST "${THREATBOOK_API_BASE}/file/upload?apikey=${apiKey}" \
  -F "file=@${filePath}" \
  -F "sandbox_type=${sandboxType}"`;

const result = execCommand(curlCmd, { silent: true, shell: true });

if (!result.success) {
  throw new Error(`上传失败:${result.error}`);
}

The report request uses the same credential-bearing command construction:

js
const curlCmd = `curl -s -X GET "${THREATBOOK_API_BASE}/file/report?apikey=${apiKey}&sha256=${sha256}&sandbox_type=${sandboxType}"`;
const result = execCommand(curlCmd, { silent: true, shell: true });

Technical Analysis

The ThreatBook API key is embedded directly into a URL passed as a command-line argument to curl. While the process is running, command-line arguments may be visible to other local users or monitoring agents through process inspection facilities.

The script also propagates execSync error messages. Such errors can include the command that failed, allowing the credential-bearing URL to reach terminal output, CI logs, telemetry, or stack traces.

In addition, the API key is interpolated into a shell command executed with shell: true. If an attacker can influence the process environment or the configured API-key value, shell syntax embedded in that value may be interpreted as commands. Although control of the environment generally requires an existing local or workflow-level capability, shell interpretation unnecessarily increases the impact of malformed or compromised configuration.

Attack Path

Credential disclosure can occur as follows:

  1. The user configures THREATBOOK_API_KEY and launches a sandbox scan.
  2. The script places the key in the curl process command line. 3 ...[truncated 1221 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace external curl execution with Node.js fetch, https, or a maintained HTTP client. This avoids exposing the key through a child-process command line.

  2. If the ThreatBook API supports it, transmit credentials in an authorization header rather than a URL query parameter.

  3. If curl must be retained, use execFileSync or spawnSync with an argument array and shell: false. This prevents shell interpretation, although command-line visibility remains a concern.

  4. Sanitize all exceptions before logging. Replace occurrences of the API key and apikey query values with a fixed redaction marker.

  5. Avoid printing full external-command strings in production errors or stack traces.

  6. Validate the API key against its documented format and reject unexpected control characters or shell metacharacters.

  7. Document key rotation procedures and advise users to rotate any key that may have appeared in process records or CI logs.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/safe-install.mjs:260
Finding

Security Review Omits Instruction Files and Most Executable File Types

Content
View full analysis

Vulnerability Details

File Location: scripts/safe-install.mjs:260-308
Vulnerability Type: Incomplete security validation and unsafe trust decision
Risk Level: High

Vulnerable Code

js
const jsFiles = [];

function scanDir(dir) {
  const files = readdirSync(dir);
  for (const file of files) {
    const filePath = path.join(dir, file);
    const stat = existsSync(filePath) ? statSync(filePath) : null;

    if (stat?.isDirectory() && !file.startsWith('.') && file !== 'node_modules') {
      scanDir(filePath);
    } else if (file.endsWith('.js') || file.endsWith('.mjs')) {
      jsFiles.push(filePath);
    }
  }
}

scanDir(skillPath);

for (const jsFile of jsFiles) {
  const content = readFileSync(jsFile, 'utf8');
  const relativePath = path.relative(skillPath, jsFile);

  for (const flag of RED_FLAGS) {
    const matches = content.match(flag.pattern);
    if (matches) {
      const flagInfo = {
        file: relativePath,
        name: flag.name,
        severity: flag.severity,
        line: content.substring(0, matches.index).split('\n').length
      };

      result.redFlags.push(flagInfo);
    }
  }
}

Technical Analysis

The local Vetter examines only files ending in .js or .mjs. It does not inspect the primary Agent instruction file SKILL.md, other Markdown instructions, shell scripts, Python, TypeScript, PowerShell, executable binaries, package manifests, or lifecycle configuration.

This limitation is especially significant for an Agent Skill because harmful behavior can be introduced through instructions rather than JavaScript. Executable payloads can also be placed in unscanned formats while benign JavaScript is supplied to make the local Vetter report no red flags.

Hidden directories and node_modules are also skipped entirely. Excluding third-party dependencies can be reasonable for performance, but it means the local ...[truncated 1965 chars]

Remediation
View remediation

Remediation Suggestions

  1. Always inspect SKILL.md, README files, metadata, manifests, lockfiles, and all text-based instruction files.

  2. Add parsers or conservative scanning for shell scripts, Python, TypeScript, PowerShell, Ruby, PHP, batch files, executable configuration, and package lifecycle hooks.

  3. Inspect file signatures and executable permission bits rather than relying only on filename extensions.

  4. Treat unsupported, obfuscated, encrypted, binary, or unreadable executable content as requiring explicit manual approval instead of silently ignoring it.

  5. Scan dependency manifests and lockfiles for install hooks, remote sources, dependency confusion, typosquatting, and unpinned dependencies. Clearly disclose when dependency contents are excluded.

  6. Replace clawhub install during preflight review with a download-only or archive-fetch operation that cannot execute installation hooks.

  7. Ensure the exact artifact that was reviewed is the artifact ultimately installed. Pin it by version and cryptographic digest to prevent a review-to-install substitution.

  8. Do not allow --no-vetter, --no-scan, --auto, or --force to silently convert failed security checks into successful automated installation. Require an explicit policy exception with auditable approval.

  9. Update documentation and status output to state the precise scan coverage and limitations rather than presenting a JavaScript-only regular-expression scan as a complete code audit.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (29)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SECURITY_PROCESS.md (reported line 113)May include surrounding context.

md
| Accessing .ssh | `\.ssh\/` | SSH 密钥窃取 |
| Accessing .aws | `\.aws\/` | AWS 凭证窃取 |
| Dangerous rm | `rm\s+-rf\s+\/` | 系统删除 |
| Reading /etc/passwd | `\/etc\/passwd` | 系统信息泄露 |

**操作**: ❌ **禁止安装**,退出码 6

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
| Accessing .ssh | `\.ssh\/` | SSH 密钥窃取 |
| Accessing .aws | `\.aws\/` | AWS 凭证窃取 |
| Dangerous rm | `rm\s+-rf\s+\/` | 系统删除 |
| Reading /etc/passwd | `\/etc\/passwd` | 系统信息泄露 |

**操作**: ❌ **禁止安装**,退出码 6

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · SECURITY_PROCESS.md (reported line 125)May include surrounding context.

md
| Use of exec() | `exec\s*\(` | 命令执行 |
| Child process exec | `child_process\.exec` | 命令执行 |
| Accessing memory files | `MEMORY\.md\|USER\.md\|SOUL\.md` | 记忆文件访问 |
| Sudo command | `sudo\s+` | 提权操作 |
| Sending sensitive data | `curl.*-d.*@.*\.ssh\|\.aws` | 数据外泄 |

**操作**: ❓ **询问任务下达者**,退出码 5(如取消)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 23)May include surrounding context.

bash
# 获取微步在线 API Key: https://s.threatbook.com
echo 'THREATBOOK_API_KEY=your_api_key_here' >> ~/.openclaw/.env

2. 使用安全安装

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · README.md (reported line 24)May include surrounding context.

bash
# 获取微步在线 API Key: https://s.threatbook.com
echo 'THREATBOOK_API_KEY=your_api_key_here' >> ~/.openclaw/.env

2. 使用安全安装

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

bash
# 获取微步在线 API Key: https://s.threatbook.com
echo 'THREATBOOK_API_KEY=your_api_key_here' >> ~/.openclaw/.env

2. 使用安全安装

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/safe-install.mjs (reported line 559)May include surrounding context.

js
```bash
# 获取微步在线 API Key: https://s.threatbook.com
echo 'THREATBOOK_API_KEY=your_api_key_here' >> ~/.openclaw/.env
```

### 2. 使用安全安装

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

md
## 红旗检测规则

### 🚨 极端风险(直接拒绝)
- `curl ... | bash` - 远程代码执行
- `wget ... | bash` - 远程代码执行
- 访问 `~/.ssh/` - SSH 密钥窃取
- 访问 `~/.aws/` - AWS 凭证窃取

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

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

md
### 🚨 极端风险(直接拒绝)
- `curl ... | bash` - 远程代码执行
- `wget ... | bash` - 远程代码执行
- 访问 `~/.ssh/` - SSH 密钥窃取
- 访问 `~/.aws/` - AWS 凭证窃取
- `rm -rf /` - 危险删除命令

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

md
- `wget ... | bash` - 远程代码执行
- 访问 `~/.ssh/` - SSH 密钥窃取
- 访问 `~/.aws/` - AWS 凭证窃取
- `rm -rf /` - 危险删除命令
- 读取 `/etc/passwd`, `/etc/shadow` - 系统文件

### 🔴 高风险(需要确认)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% 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 141)May include surrounding context.

md
- `wget ... | bash` - 远程代码执行
- 访问 `~/.ssh/` - SSH 密钥窃取
- 访问 `~/.aws/` - AWS 凭证窃取
- `rm -rf /` - 危险删除命令
- 读取 `/etc/passwd`, `/etc/shadow` - 系统文件

### 🔴 高风险(需要确认)

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

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

md
- 访问 `~/.ssh/` - SSH 密钥窃取
- 访问 `~/.aws/` - AWS 凭证窃取
- `rm -rf /` - 危险删除命令
- 读取 `/etc/passwd`, `/etc/shadow` - 系统文件

### 🔴 高风险(需要确认)
- `eval()` - 代码注入风险

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `SKILL.md` - Skill 元数据和使用说明

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `scripts/safe-install.mjs` - 主安装脚本

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The file presents all user-facing instructions and interaction examples in Chinese, including prompts and operational guidance, but does not indicate that other languages are supported or that Chinese is required for a region-specific compliance reason. This can violate a language/locale policy when users are not given an explicit opt-in or alternative.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 121)May include surrounding context.

md
|---------|---------|------|
| **🟢 LOW** | 标准文件操作、日志记录 | ✅ 通过 |
| **🟡 MEDIUM** | 网络请求、子进程、base64 解码 | ✅ 通过,记录 |
| **🔴 HIGH** | eval()、访问记忆文件、sudo | ❓ 询问任务下达者 |
| **⛔ EXTREME** | curl\|bash、访问.ssh/.aws、危险 rm | ❌ 禁止安装 |

**信任层级**:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documented process says downloaded Skills are automatically uploaded to the ThreatBook third-party sandbox, but it does not clearly require an explicit user warning or consent for external transmission of untrusted package contents. This can leak proprietary code, embedded secrets, or user data from the Skill to an external service, which is a real security and privacy risk even if the goal is defensive scanning.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SECURITY_PROCESS.md (reported line 125)May include surrounding context.

md
| Use of exec() | `exec\s*\(` | 命令执行 |
| Child process exec | `child_process\.exec` | 命令执行 |
| Accessing memory files | `MEMORY\.md\|USER\.md\|SOUL\.md` | 记忆文件访问 |
| Sudo command | `sudo\s+` | 提权操作 |
| Sending sensitive data | `curl.*-d.*@.*\.ssh\|\.aws` | 数据外泄 |

**操作**: ❓ **询问任务下达者**,退出码 5(如取消)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/safe-install.mjs (reported line 167)May include surrounding context.

js
| Use of exec() | `exec\s*\(` | 命令执行 |
| Child process exec | `child_process\.exec` | 命令执行 |
| Accessing memory files | `MEMORY\.md\|USER\.md\|SOUL\.md` | 记忆文件访问 |
| Sudo command | `sudo\s+` | 提权操作 |
| Sending sensitive data | `curl.*-d.*@.*\.ssh\|\.aws` | 数据外泄 |

**操作**: ❓ **询问任务下达者**,退出码 5(如取消)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The --auto/--yes/-y mode explicitly bypasses confirmations and proceeds with installation even when earlier checks classify a Skill as high-risk, suspicious, low-rated, or API-indeterminate. In a security-gating tool, removing human approval for risky outcomes undermines the core safety control and can enable unattended installation of malicious Skills in CI/CD or automation contexts.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises operational behavior that clearly requires shell, network, and environment-variable access, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates an authorization ambiguity where a host or reviewer cannot enforce least privilege, increasing the chance the skill runs with broader capabilities than intended.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This markdown file presents the skill name, description, usage instructions, warnings, and examples entirely in Chinese. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified or alternatives are offered.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The natural-language description is written entirely in Chinese, which can impose a language/locale expectation without offering user choice or documenting a region-specific reason. Under the stated policy, language constraints should be optional or clearly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code file contains natural-language comments and CLI help/output strings that are exclusively in Chinese, including the main description, help text, prompts, and status messages. Under the policy, forcing a specific language without opt-in is a locale/language policy violation because users are not offered an alternative language or any documented justification for the restriction.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The top-level documentation promises that suspicious files will wait for confirmation, but the main decision path allows both --auto and --force to continue installation without any confirmation whenever findings require review. In a tool whose purpose is secure installation, this undermines the trust model and can lead to unsafe installs under misleading safety assurances.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.dynamic_code_execution

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/safe-install.mjs:137

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/safe-install.mjs:158