T09 · Insecure Skill Coding Practices
- Location
examples/example_usage.py:103- Finding
Shell Command Injection in the Documented Command-Line Execution Pattern
- Content
View full analysis
Vulnerability Details
File Location:
examples/example_usage.py, lines 103–116
Vulnerability Type: Shell command injection through unsafe command-string construction
Risk Level: MediumVulnerable Code
python # 转换为JSON字符串 content_json = json.dumps(content_list, ensure_ascii=False) output_path = r"E:\Desktop\技术文档模板.docx" # 构建命令行 cmd = f'python scripts/word_creator.py --title "{title}" --content \'{content_json}\' --output "{output_path}"' print(f"命令行调用示例:") print(f" {cmd}") # 实际执行(注释掉,仅展示) # import subprocess # result = subprocess.run(cmd, shell=True, capture_output=True, text=True) # print(result.stdout) # print(result.stderr)Technical Analysis
The example constructs a shell command by directly interpolating
title,content_json, andoutput_pathinto a single string. It then demonstrates executing that string withsubprocess.run(..., shell=True).Shell quoting does not constitute safe input validation. If any interpolated value contains shell metacharacters, quote delimiters, command separators, redirection operators, or command-substitution syntax, the value can escape its intended argument and be interpreted as a separate command by the operating-system shell.
The execution lines are currently commented out, so the checked-in example does not directly execute the command. However, the comments explicitly instruct users to uncomment this pattern for actual use. The vulnerability becomes exploitable when the example is enabled, copied into production code, or adapted to process externally supplied document fields.
Attack Path
- An application accepts an attacker-controlled document title, content value, or output path.
- The application uses the demonstrated f-string to place that value into
cmd. - The attacker includes shell syntax that closes the surrounding quote and appends another command.
- The application invokes
subprocess.run(cmd, shell=True, ...). - The operating-system shell parses the ...[truncated 919 chars]
- Remediation
View remediation
Remediation Suggestions
Do not pass dynamically constructed command strings to a shell. Invoke Python with an argument list and leave shell processing disabled:
python import subprocess import sys result = subprocess.run( [ sys.executable, "scripts/word_creator.py", "--title", title, "--content", content_json, "--output", output_path, ], shell=False, capture_output=True, text=True, check=True, )Additional hardening measures:
- Remove the insecure
shell=Trueexample so users are not encouraged to copy it. - Use
sys.executableinstead of a barepythoncommand to select the current trusted interpreter. - Implement and validate the advertised command-line arguments in
word_creator.pybefore documenting command-line use. - Restrict output paths to an approved directory when paths can originate from untrusted users.
- Validate input types and impose reasonable length limits on titles and document content.
- Handle
subprocess.CalledProcessErrorwithout exposing sensitive command output or local path details.
- Remove the insecure
