T09 · Insecure Skill Coding Practices
- Location
analyze.sh:20- Finding
Arbitrary Python Code Execution Through Unsanitized Company Input
- Content
View full analysis
/dev/null | \ python3 -c " import sys, re, html content = sys.stdin.read() results = re.findall(r'class=\"result__snippet\">(.*?)', content, re.DOTALL) for i, r in enumerate(results[:5]): text = html.unescape(re.sub(r'<[^>]+>', '', r)).strip() if text: print(f'- {text}') " 2>/dev/null || echo "- (search unavailable — run with an AI agent for better results)" } ``` ### Technical Analysis The `query` variable contains data derived from the user-controlled command-line argument. Line 20 interpolates that value directly into Python source code: ```bash python3 -c "import urllib.parse; print(urllib.parse.quote('$query'))" ``` Although the shell variable is inside shell double quotes, its value is inserted into a single-quoted Python string. Shell quoting does not protect the resulting Python program. An attacker can include a single quote and Python syntax in the company argument to terminate the intended string and add arbitrary statements. For example, an argument shaped like the following can inject an operating-system command: ```text x')); __import__("os").system("touch pwned"); # ``` When incorporated into the generated Python source, the injected statement executes under the privileges of the user running the skill. The trailing Python comment suppresses the legitimate query suffix and remaining syntax. ### Attack Path 1. An attacker supplies a crafted company name to `analyze.sh`. 2. The value is assigned to `COMPANY`. 3. `SEARCH_NAME` removes URL-related components but does not reject Python metacharacters, quotes, semicol ...[truncated 1137 chars]- Remediation
View remediation
/dev/null | python3 -c ' import sys, re, html content = sys.stdin.read() results = re.findall(r"class=\"result__snippet\">(.*?)", content, re.DOTALL) for result in results[:5]: text = html.unescape(re.sub(r"<[^>]+>", "", result)).strip() if text: print(f"- {text}") ' 2>/dev/null || echo "- (search unavailable — run with an AI agent for better results)" } ``` Additional hardening measures: 1. Treat all command-line arguments as untrusted data. 2. Never construct source code by concatenating or interpolating user input. 3. Add regression tests containing single quotes, double quotes, semicolons, newlines, backticks, shell substitutions, and Python comment characters. 4. Verify that malicious-looking inputs are URL-encoded as plain data and never executed. 5. Consider implementing URL encoding entirely in one language or using a dedicated command-line encoder to reduce nested quoting complexity. ]]>
