T09 · Insecure Skill Coding Practices
- Location
index.js:15- Finding
Shell Command Injection Through the Skill Installation Path
- Content
View full analysis
Vulnerability Details
File Location:
index.js, lines 1 and 15–17
Vulnerability Type: Shell command injection
Risk Level: MediumVulnerable Code
javascript const { execSync } = require('child_process'); // ... const scriptPath = path.join(__dirname, 'bili_fetcher.py'); const result = execSync(`python "${scriptPath}"`, { encoding: 'utf-8' });Technical Analysis
The skill uses
execSync()with a dynamically constructed command string. String-form process execution is interpreted by a system shell. Although tool arguments are not included in the command,scriptPathis derived from__dirnameand interpolated directly into it.Wrapping the path in double quotes does not provide safe shell escaping. If the installation directory contains a double quote followed by shell metacharacters, its name can terminate the quoted argument and append an additional command. This converts control over the installation path into arbitrary shell command execution.
Attack Path
- An attacker creates, supplies, or persuades the user to use a skill installation directory whose path contains a quote and shell command metacharacters.
- OpenClaw loads the skill from that attacker-influenced path.
- The user or agent invokes
bili_fetch_tool. index.jsinserts the path into the command string passed toexecSync().- The system shell parses the embedded metacharacters as command syntax.
- The attacker-supplied command executes with the privileges of the OpenClaw process.
Exploitation requires the attacker to influence the skill's installation path; no direct injection through the tool's
argsparameter was identified.Impact Assessment
Successful exploitation permits arbitrary local command execution under the operating-system account running OpenClaw. Depending on that account's permissions, an attacker could read or modify accessible files, execute programs, access user- ...[truncated 198 chars]
- Remediation
View remediation
Remediation Suggestions
Avoid invoking a shell. Use
execFileSync()orspawnSync()and pass the script path as a distinct argument:javascript const { execFileSync } = require('child_process'); const path = require('path'); const scriptPath = path.join(__dirname, 'bili_fetcher.py'); const result = execFileSync('python', [scriptPath], { encoding: 'utf-8', windowsHide: true });Additional hardening measures:
- Use an explicitly configured and trusted Python executable rather than relying on ambiguous command resolution.
- Validate configuration-derived executable paths before use.
- Set an execution timeout and output-size limit to reduce denial-of-service risk.
- Return a generic error to untrusted callers while recording detailed process errors only in protected logs.
- Do not attempt to repair the current implementation solely through manual quoting; argument-based, shell-free process invocation is the reliable mitigation.
