T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/flirt_cron.sh:58
- Finding
- Python Source Injection Through Attacker-Controlled State and Message Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/flirt_cron.sh:58-80` and `scripts/flirt_cron.sh:232-241` **Vulnerability Type**: Data-to-code injection **Risk Level**: High ### Complete Vulnerable Code ```bash calc_time_diff() { local last_file="$1" local default_time="2026-03-15 01:35:00" if [ -f "$last_file" ]; then LAST_CHAT=$(cat "$last_file") else LAST_CHAT="$default_time" echo "$default_time" > "$last_file" fi python3 -c " from datetime import datetime last = datetime.strptime('$LAST_CHAT', '%Y-%m-%d %H:%M:%S') now = datetime.now() diff = now - last hours = diff.total_seconds() / 3600 if hours < 1: mins = int(diff.total_seconds() / 60) print(f'{mins}分钟') elif hours < 24: print(f'{int(hours)}小时') else: days = int(hours / 24) print(f'{days}天{int(hours%24)}小时') " 2>/dev/null || echo "一会儿" } ``` A second injection sink embeds the selected library entry in Python source: ```bash # 更新状态 python3 -c " import json with open('$FLIRT_STATE', 'r+') as f: d = json.load(f) d['sent_flirts'].append('$SELECTED_FLAIR') d['last_flirt_date'] = '$(date +%Y-%m-%d)' f.seek(0) json.dump(d, f, ensure_ascii=False) f.truncate() " 2>/dev/null ``` ### Technical Analysis The script reads `LAST_CHAT` from a state file and `SELECTED_FLAIR` from the customizable flirt library, then inserts both values directly into source code supplied to `python3 -c`. Shell quoting around the command does not make the resulting Python source safe. A value containing a single quote followed by valid Python statements can terminate the intended string literal and inject additional Python operations. Python can import `os` or `subprocess`, so successful injection can execute arbitrary operating-system commands with the privileges of the scheduled script. The documented cron example uses a path under `/root`, indicating that the script may be scheduled by root. In that deployment, th ...[truncated 1246 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Never interpolate file or message content into Python source code. - Pass values as positional arguments or environment variables and read them through `sys.argv` or `os.environ`. - Move state handling into a dedicated Python file that parses JSON and timestamps strictly as data. - Validate timestamps with an allowlisted format before processing them. - Serialize flirt entries through a JSON encoder rather than constructing Python string literals. - Restrict the library, state files, and containing directories to the service account, using permissions such as `0700` for directories and `0600` for files. - Execute the cron job under a dedicated unprivileged account rather than root. - Add tests using quotes, backslashes, newlines, and Python syntax to verify that content cannot alter program structure. ]]>
