T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/cultural_tourism_bilibili_report.py:554
- Finding
- Shell Command Injection and Persistent Cron Injection Through the Subscription Keyword<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cultural_tourism_bilibili_report.py`, lines 554–559 **Vulnerability Type**: OS command injection and scheduled-task injection **Risk Level**: Critical ### Vulnerable Code ```python script_path = os.path.abspath(__file__) cron_line = f"0 9 * * * /usr/bin/python3 {script_path} --keyword {keyword} --no-open" try: subprocess.run( f'(crontab -l 2>/dev/null; echo "{cron_line}") | crontab -', shell=True, check=True, capture_output=True ) ``` ### Technical Analysis The `keyword` value originates from the user-controlled `--keyword` command-line argument and is interpolated directly into a command executed with `shell=True`. Neither the keyword nor `script_path` is validated or safely quoted. The surrounding double quotes do not prevent shell expansion. Shell constructs such as command substitution, backticks, embedded quotes, and newline characters can alter command behavior. Newlines can additionally insert arbitrary cron entries, converting immediate command injection into persistent execution. ### Attack Path 1. An attacker supplies or induces the Agent to use a malicious subscription keyword containing shell syntax. 2. The Agent invokes the script with `--subscribe` and the crafted keyword. 3. `install_subscription()` inserts the keyword into `cron_line`. 4. The complete string is passed to a shell through `subprocess.run(..., shell=True)`. 5. The shell evaluates the injected syntax with the privileges of the user running the Skill. 6. A crafted newline or cron expression can also register an attacker-controlled recurring command. ### Impact Assessment Successful exploitation provides arbitrary command execution under the Agent user's account. The attacker could read or modify user-accessible files, steal credentials, download additional payloads, alter the user's crontab, or establish recurring execution. No administrative privilege is inherently obtained, but the comp ...[truncated 64 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Remove `shell=True` and never construct scheduler commands by concatenating untrusted strings. - Reject keywords containing control characters, especially carriage returns, newlines, null bytes, quotes, backticks, dollar signs, and shell metacharacters. - Generate a crontab file as structured data and install it with an argument-vector call such as `subprocess.run(["crontab", temporary_file], check=True)`. - If cron syntax must be generated, serialize each program argument with a robust quoting strategy and test it against newline injection. - Use a stable identifier or comment to locate and replace the Skill's own entry rather than appending duplicate entries. - Display the exact scheduled command and obtain explicit user confirmation before modifying the crontab. ]]>
