T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/lookup.sh:58
- Finding
- Arbitrary Python Code Execution Through an Unsafely Interpolated Address## Vulnerability Details **File Location**: `scripts/lookup.sh:58-61` **Vulnerability Type**: Command injection through dynamically generated Python source code **Risk Level**: High ```bash if [[ -n "$ADDRESS" ]]; then ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$ADDRESS'))") curl -s "${BASE_URL}/request/${VERSION}?address=${ENCODED}" \ -H "X-API-KEY: ${ZIPTAX_API_KEY}" | python3 -m json.tool ``` ### Technical Analysis The value of `ADDRESS` is controlled by the `--address` command-line argument and is interpolated directly into the source code passed to `python3 -c`. Shell quoting prevents ordinary shell word splitting, but it does not make the resulting Python program safe. An address containing a single quote and valid Python syntax can terminate the intended string literal and append arbitrary Python statements. The Python interpreter then executes those statements with the same operating-system identity, environment variables, filesystem permissions, and network access as the script. This behavior is not necessary for URL encoding. User data should be passed to Python through an argument or standard input, never embedded into executable source code. ### Attack Path 1. An attacker influences the address supplied to the Skill or persuades a user or agent to perform a lookup using a crafted address. 2. The attacker supplies Python syntax that closes the quoted address and adds a statement, for example: ```text ')); __import__("os").system("id"); # ``` 3. The shell expands the crafted value inside the `python3 -c` argument. 4. Python parses the injected text as executable source code. 5. The injected operating-system command runs before the ZipTax request is made. The payload could replace `id` with commands that read accessible files, inspect environment variables, make outbound requests, or modify resources writable by the current account. ### Impact Assessment ...[truncated 568 chars]
- Remediation
- ## Remediation Suggestions Pass the address as a data argument rather than inserting it into Python source: ```bash ENCODED=$( python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1]))' \ "$ADDRESS" ) ``` Alternatively, use a URL-aware HTTP client that accepts query parameters separately. Apply strict argument-count checks before reading `$2`, validate lookup inputs according to their expected formats, and add regression tests containing quotes, semicolons, newlines, command substitutions, and Python syntax. The tests should verify that such input is encoded as data and never executed.
