T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/click.sh:15
- Finding
- Arbitrary Local Python Code Execution Through Unquoted Heredoc Argument Interpolation## Vulnerability Details **File Location**: `scripts/click.sh:15-24` **Additional Affected Locations**: `scripts/click_coords.sh:22-31`, `scripts/eval_js.sh:13-22`, `scripts/get_content.sh:21-36`, `scripts/hover.sh:10-19`, `scripts/navigate.sh:12-22`, `scripts/press_key.sh:16-25`, `scripts/screenshot.sh:20-30`, `scripts/scroll.sh:12-35`, `scripts/select.sh:12-23`, `scripts/start_session.sh:25-55`, `scripts/type.sh:12-21`, and `scripts/wait_for.sh:12-21` **Vulnerability Type**: Python source-code injection **Risk Level**: High ### Vulnerable Code A representative vulnerable implementation is: ```bash python3 - <<PYEOF import os, sys HELPER = "$SCRIPT_DIR/_connect.py" exec(open(HELPER).read()) try: page.click("""$SELECTOR""") print(f"Clicked: $SELECTOR") finally: cleanup() PYEOF ``` The same unsafe pattern is used for other caller-controlled values. Representative examples include: ```bash page.goto("$URL", wait_until="$WAIT_UNTIL") ``` ```bash result = page.evaluate("""$JS""") ``` ```bash page.fill("""$SELECTOR""", """$TEXT""") ``` ```bash page.screenshot(path="$OUTPUT", full_page=full_page) ``` ```bash page.wait_for_selector("""$SELECTOR""", timeout=int("$TIMEOUT_MS")) ``` ### Technical Analysis The scripts construct a Python program in an unquoted shell heredoc and directly interpolate command-line arguments into Python string literals. Triple-quoted strings do not safely serialize arbitrary input. A value containing a closing triple quote can terminate the intended literal and append new Python statements. For example, a malicious selector shaped like the following can break out of the generated string: ```text x"""); __import__("os").system("id"); # ``` It causes the generated Python source to contain an attacker-controlled statement conceptually equivalent to: ```python page.click("""x""") __import__("os").system("id") ``` The inje ...[truncated 2215 chars]
- Remediation
- ## Remediation Suggestions Do not generate Python source code by interpolating shell arguments. Pass each value as a normal process argument and use a single-quoted heredoc so the shell cannot expand its contents: ```bash python3 - "$SCRIPT_DIR/_connect.py" "$SELECTOR" <<'PY' import sys helper = sys.argv[1] selector = sys.argv[2] exec(compile(open(helper, encoding="utf-8").read(), helper, "exec")) try: page.click(selector) print(f"Clicked: {selector}") finally: cleanup() PY ``` Apply the same design to every affected script: 1. Pass selectors, URLs, text, JavaScript, paths, keys, and option values through `sys.argv` or a safely encoded data channel such as JSON. 2. Quote heredoc delimiters as `<<'PY'`. 3. Validate numeric fields in Bash and Python before use. 4. Restrict enumerated values such as mouse buttons and page load states to explicit allowlists. 5. Validate navigation schemes and screenshot destinations according to the intended trust boundary. 6. Add regression tests containing quotes, triple quotes, newlines, backslashes, Unicode, and attempted Python statements. 7. Prefer a shared Python command-line program using `argparse` over separate shell-generated Python fragments.
