T09 · Insecure Skill Coding Practices
- Location
index.js:18- Finding
OS Command Injection Through the Directory Path Argument
- Content
View full analysis
Vulnerability Details
File Location:
index.js, lines 18-23
Vulnerability Type: OS command injection
Risk Level: CriticalVulnerable Code
javascript const pythonPath = '/usr/bin/python3'; const scriptPath = '/home/jiajiexu/.nvm/versions/node/v22.20.0/lib/node_modules/@qingchencloud/openclaw-zh/skills/folder_inspector/scripts/file_scanner.py'; // Execute Python and capture its output const stdout = execSync(`${pythonPath} ${scriptPath} "${args.path}"`);Technical Analysis
The skill passes the untrusted
args.pathvalue into a command string executed bychild_process.execSync. This API invokes a shell, so shell metacharacters in the path are interpreted as command syntax.Surrounding the value with double quotes does not make this safe. An attacker can include a double quote in the supplied path to terminate the quoted argument and then append shell operators and commands. The parameter schema only requires a string and does not prevent quotes, semicolons, command substitutions, redirections, or other shell syntax.
An illustrative malicious argument is:
text "; id > /tmp/folder_inspector_proof; #It produces a command equivalent to:
sh /usr/bin/python3 /path/to/file_scanner.py ""; id > /tmp/folder_inspector_proof; #"The shell consequently executes the injected
idcommand independently of the Python scanner.Attack Path
- An attacker gains the ability to invoke the skill or influence its
pathargument. - The attacker submits a path containing a closing quote followed by shell commands, such as
"; id > /tmp/folder_inspector_proof; #. - The handler interpolates the value directly into the command string.
execSyncpasses the resulting string to a shell.- The shell interprets and executes the appended command.
- The attacker can replace the demonstration command with commands that read, modify, delete, or transmit data accessib ...[truncated 702 chars]
- An attacker gains the ability to invoke the skill or influence its
- Remediation
View remediation
Remediation Suggestions
Do not construct a shell command containing user-controlled data. Invoke Python with an argument-array API and disable shell processing.
javascript const path = require('path'); const { execFileSync } = require('child_process'); const pythonPath = '/usr/bin/python3'; const scriptPath = path.join(__dirname, 'scripts', 'file_scanner.py'); const stdout = execFileSync( pythonPath, [scriptPath, args.path], { encoding: 'utf8', shell: false } );Additional hardening should include:
- Require
args.pathto be a nonempty absolute path. - Resolve and normalize the path before use.
- If the skill is intended to inspect only approved locations, enforce an explicit allowlist of root directories and verify the resolved path remains beneath an allowed root.
- Run the skill under a dedicated, least-privileged operating-system account.
- Apply execution timeouts and output-size limits to the child process.
- Resolve the bundled scanner relative to
__dirnamerather than using a machine-specific global installation path. - Treat validation as defense in depth; argument-array execution must remain the primary command-injection control.
- Require
