T09 · Insecure Skill Coding Practices
- Location
scripts/watch_intent.py:124- Finding
Shell Command Injection Through User-Controlled Rule Names
- Content
View full analysis
str: quoted = re.search(r'"([^"]{2,40})"', text) if quoted: return quoted.group(1).strip() ``` ```python def _build_plan_hints(name: str, delivery_mode: str, schedule: dict[str, Any]) -> dict[str, Any]: command = f'python {SCRIPT_PATH} watch-check "{name}" --json' if delivery_mode == "alert": command = f'python {SCRIPT_PATH} watch-check "{name}" --alerts-only --json' persist_command = f'python {SCRIPT_PATH} watch-upsert {{request_json}}' return { "recommended_command": command, "persist_command_template": persist_command, "cron": schedule.get("cron"), "cron_example": f'{schedule["cron"]} {command}' if schedule.get("cron") else None, } ``` ```python recommended_command = (rule.get("plan_hints") or {}).get("recommended_command") persist_command = f'python {SCRIPT_PATH} watch-upsert {text!r}' cron_payload = None if schedule.get("cron"): cron_payload = { "expr": schedule["cron"], "command": recommended_command, "description": f'{rule["name"]} / {schedule.get("label") or schedule["cron"]}', } ``` ### Technical Analysis The rule name can be taken directly from a quoted portion of a user-controlled natural-language request. The value is subsequently interpolated into a shell command inside double quotes without shell-safe escaping. Double quotes do not neutralize all shell syntax. Command substitutions such as `$()` and backticks are still evaluated by common POSIX shells. Consequently, a rule name such as: ```text "$(touch /tmp/injected)" item every hour ``` can produce a recommended command resembling: ```bash python s ...[truncated 2036 chars]- Remediation
View remediation
