T09 · Insecure Skill Coding Practices
Error
- Location
- transcribe.sh:87
- Finding
- Arbitrary Python Code Execution Through the Prompt Argument<![CDATA[ ## Vulnerability Details **File Location**: `transcribe.sh:87` **Vulnerability Type**: Python source-code injection **Risk Level**: High ### Vulnerable Code ```bash [[ -n "$PROMPT" ]] && QUERY="${QUERY}&initial_prompt=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${PROMPT}'))" 2>/dev/null || echo "${PROMPT}")" ``` ### Technical Analysis The user-controlled `PROMPT` value is interpolated directly into Python source passed to `python3 -c`. The shell's quoting protects the value from direct shell interpretation, but it does not make the resulting Python source safe. Quotes and Python syntax contained in the expanded value are parsed by the Python interpreter. An attacker can supply a prompt that closes the Python string and injects additional Python statements. For example, a value following this pattern can invoke operating-system commands: ```text '); __import__("os").system("id"); # ``` The constructed Python program would contain attacker-controlled executable syntax. Suppressing Python's standard error output does not prevent exploitation and may make failed or attempted exploitation less visible. The fallback `echo "${PROMPT}"` is also not a safe URL-encoding mechanism, although it does not independently produce code execution because the value remains quoted there. ### Attack Path 1. An attacker supplies or convinces an agent to use a malicious value for `--prompt`. 2. The argument parser stores that value in `PROMPT`. 3. Line 87 inserts it directly between Python string delimiters in the `python3 -c` source. 4. The malicious value terminates the intended string and appends Python statements. 5. `python3` executes those statements with the privileges and environment of the user running the Skill. 6. The injected code can invoke local commands, read accessible files, modify data, or initiate additional network requests. ### Impact Assessment Successful exploitation provides arbitrary local code execution under the accoun ...[truncated 355 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Never interpolate untrusted data into executable source. Pass the prompt as a separate positional argument: ```bash ENCODED_PROMPT=$( python3 -c \ 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' \ "$PROMPT" ) QUERY="${QUERY}&initial_prompt=${ENCODED_PROMPT}" ``` A stronger design is to avoid manually assembling the query string and let `curl` perform URL encoding: ```bash curl \ --silent \ --show-error \ --fail \ --request POST \ --form "audio_file=@${INPUT_FILE}" \ --get \ --data-urlencode "task=${TASK}" \ --data-urlencode "output=${OUTPUT_FORMAT}" \ --data-urlencode "initial_prompt=${PROMPT}" \ "${BASE_URL}/asr" ``` Adapt the request construction as necessary to preserve the required POST and multipart semantics. In addition: - Validate `TASK` and `OUTPUT_FORMAT` against strict allowlists. - Validate language codes against the formats accepted by the service. - Add automated tests containing quotes, semicolons, newlines, Python syntax, and shell metacharacters. - Do not silently fall back to an unencoded prompt if encoding fails; terminate with an explicit error instead. ]]>
