T09 · Insecure Skill Coding Practices
- Location
scripts/self_check.py:501- Finding
Shell Command Injection Through a Crafted Log Filename
- Content
View full analysis
Tuple[int, str, str]: """运行命令并返回 (returncode, stdout, stderr)""" try: result = subprocess.run( cmd, shell=shell, capture_output=True, text=True, timeout=timeout ) return result.returncode, result.stdout.strip(), result.stderr.strip() except subprocess.TimeoutExpired: return -1, "", "Timeout" except Exception as e: return -1, "", str(e) ``` ### Technical Analysis The script finds the newest `*.log` file in `~/.openclaw/logs` and embeds its full path directly into a command string passed to `subprocess.run()` with `shell=True`. Although the path is surrounded by single quotes, POSIX filenames may themselves contain single-quote characters, semicolons, redirection operators, and other shell metacharacters. A single quote in the filename can terminate the intended quoted argument, after which the remaining filename content is parsed as shell syntax. For example, a filename resembling the following can introduce an additional command: ```text audit';id>self-check-proof;#.log ``` The resulting command is structurally equivalent to: ```sh tail -100 '/home/user/.openclaw/logs/audit';id>self-check-proof;#.log' ``` Consequently, the shell runs both `tail` and the injected `id` command. The issue is caused by combining attacker-influenced filesystem data with string-based shell execution; quoting alone does not safely handle embedded quote characters. ### Attack Path 1. An attacker obtains the ...[truncated 1702 chars]- Remediation
View remediation
Tuple[int, str, str]: result = subprocess.run( cmd, shell=False, capture_output=True, text=True, timeout=timeout, ) return result.returncode, result.stdout.strip(), result.stderr.strip() ``` 2. Convert commands that do not require shell features into argument arrays. 3. Replace shell pipelines and redirections with Python processing or explicitly connected subprocesses. 4. Avoid treating shell quoting as a substitute for argument-safe process invocation. 5. Add a regression test using a log filename containing quotes, semicolons, spaces, and redirection characters, verifying that no additional command executes. 6. Restrict permissions on `~/.openclaw/logs` so that only the intended user and trusted logging processes can create or rename files there. ]]>
