T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/aithon-search.sh:13
- Finding
- Python Code Injection Through Unsafely Interpolated Search Query## Vulnerability Details **File Location**: `scripts/aithon-search.sh`, line 13 **Vulnerability Type**: Python code injection caused by unsafe string interpolation **Risk Level**: High ### Vulnerable Code ```bash URL="${BASE}?q=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${QUERY}'))")&limit=${LIMIT}" ``` ### Technical Analysis The script directly interpolates the untrusted `QUERY` positional argument into source code passed to `python3 -c`. Although the intended operation is URL encoding, the query is placed inside a single-quoted Python string without escaping. A query containing a single quote and additional Python syntax can terminate the intended string and inject arbitrary Python statements. For example, an input shaped like the following can execute a local command: ```text x')); __import__("os").system("id"); # ``` This is a local code-execution vulnerability, not a remote `curl | bash` issue. The separate pipeline on line 21 sends the HTTP response to `python3 -m json.tool`, which parses and formats JSON rather than executing it. ### Attack Path 1. An attacker controls a catalog search query or persuades an operator or agent to search for a crafted value. 2. The crafted value is passed as the first argument to `aithon-search.sh`. 3. Line 13 embeds the value directly into the program supplied to `python3 -c`. 4. The crafted quote terminates the intended Python string. 5. The Python interpreter evaluates the injected statements before the catalog request is made. 6. The injected code can invoke operating-system commands with the privileges of the account running the Skill. ### Impact Assessment Successful exploitation permits arbitrary code execution under the invoking user's OS account. The attacker could read or modify files accessible to that account, access locally available credentials or API tokens, alter project data, execute network requests, or install additional user-level ...[truncated 277 chars]
- Remediation
- ## Remediation Suggestions Pass the query as a separate Python argument rather than embedding it in Python source: ```bash ENCODED_QUERY="$( python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1]))' "$QUERY" )" URL="${BASE}?q=${ENCODED_QUERY}&limit=${LIMIT}" ``` Apply the same URL encoding to `CATEGORY`, and validate `LIMIT` as a bounded positive integer before adding it to the URL: ```bash if ! [[ "$LIMIT" =~ ^[0-9]+$ ]] || (( LIMIT < 1 || LIMIT > 100 )); then printf 'Invalid limit: expected an integer from 1 to 100\n' >&2 exit 2 fi ``` Prefer `curl --get --data-urlencode` so URL construction and encoding are delegated to a purpose-built interface. Add regression tests covering single quotes, double quotes, semicolons, command substitutions, backslashes, Unicode, and newline characters. As defense in depth, run the helper with only the filesystem, credential, and network access required for catalog search. Do not expose unrelated API tokens or sensitive files to the process.
