T09 · Insecure Skill Coding Practices
- Location
scripts/search.sh:11- Finding
Arbitrary Command Execution Through Python Code Injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/search.sh, line 11
Vulnerability Type: Python source-code injection caused by unsafe interpolation of user-controlled input
Risk Level: HighVulnerable Code
bash ENCODED=$(python3 -c "import urllib.parse; print(urllib.parse.quote('''$QUERY'''))")Technical Analysis
The script reads its first positional argument into
QUERYand directly interpolates that value into the source code passed topython3 -c. Triple-quoting the value does not make it safe. A crafted query can terminate the Python string literal and append arbitrary Python statements.For example, a query with the following structure can escape the intended string and invoke an operating-system command:
text x'''); __import__('os').system('id'); #The resulting Python program executes
os.system('id'). Shell quoting does not prevent this issue because the injection occurs in the dynamically constructed Python source after the shell expands$QUERY.Attack Path
- An attacker supplies a malicious financial query or induces an agent to process one.
- The agent invokes
scripts/search.shand passes the crafted content as its first argument. - The script stores the content in
QUERY. - Line 11 interpolates
QUERYinto the program supplied topython3 -c. - The malicious content closes the intended triple-quoted string and appends Python statements.
- Python executes the injected statements with the permissions of the Skill runner before the API request is made.
Impact Assessment
Successful exploitation provides arbitrary command execution with the operating-system privileges of the process running the Skill. An attacker could consequently:
- Read files accessible to the Skill runner, including workspace data and available credentials.
- Modify or delete accessible files.
- Launch local programs and network clients.
- Exfiltrate accessible information to external systems.
- Establish addition ...[truncated 256 chars]
- Remediation
View remediation
Remediation Suggestions
Never place untrusted input inside dynamically generated source code. Pass the query to Python as a separate argument:
bash ENCODED=$(python3 -c \ 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1]))' \ "$QUERY")A simpler and preferable solution is to let
curlperform URL encoding, eliminating the dynamic Python execution entirely:bash curl --silent --show-error --fail-with-body \ --location \ --get \ --data-urlencode "query=$QUERY" \ --connect-timeout 10 \ --max-time 30 \ "https://terminal-x.ai/api/lite-search"Additional hardening measures should include:
- Keep every expansion of
QUERYproperly quoted. - Add automated tests containing quotes, triple quotes, semicolons, newlines, shell metacharacters, and the demonstrated payload.
- Use explicit connection and overall request timeouts.
- Use
--fail-with-bodyso HTTP failures produce a nonzero exit status. - Run the Skill under a least-privileged account with minimal filesystem and credential access to limit the consequences of future defects.
- Keep every expansion of
