T09 · Insecure Skill Coding Practices
Error
- Location
- index.js:18
- Finding
- OS Command Injection Through the Directory Path Argument## Vulnerability Details **File Location**: `index.js`, lines 18-23 **Vulnerability Type**: OS command injection **Risk Level**: Critical ### Vulnerable 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.path` value into a command string executed by `child_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 `id` command independently of the Python scanner. ### Attack Path 1. An attacker gains the ability to invoke the skill or influence its `path` argument. 2. The attacker submits a path containing a closing quote followed by shell commands, such as `"; id > /tmp/folder_inspector_proof; #`. 3. The handler interpolates the value directly into the command string. 4. `execSync` passes the resulting string to a shell. 5. The shell interprets and executes the appended command. 6. The attacker can replace the demonstration command with commands that read, modify, delete, or transmit data accessib ...[truncated 702 chars]
- 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.path` to 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 `__dirname` rather than using a machine-specific global installation path. - Treat validation as defense in depth; argument-array execution must remain the primary command-injection control.
