T09 · Insecure Skill Coding Practices
- Location
SKILL.md:121- Finding
Untrusted JSON-RPC Response Interpolated into Executable Python Code
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 121–127
Vulnerability Type: Code injection through unsafe interpolation of network-controlled data
Risk Level: HighVulnerable Code
bash LATEST=$(curl -fsSL -X POST https://mainnet.qelt.ai \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' | python3 -c "import sys,json; print(json.load(sys.stdin)['result'])") # Then query a bounded recent range (last ~1000 blocks ≈ 83 minutes on QELT) # Clamp at 0 so the start block is never negative on a low-height chain (e.g. fresh testnet). FROM_HEX=$(python3 -c "latest=int('$LATEST',16); print(hex(max(0, latest - 1000)))")Technical Analysis
The
LATESTvariable is derived from a remote JSON-RPC response. Although the response is parsed as JSON, the resultingresultfield is not validated as a hexadecimal block number. It is subsequently interpolated directly into a double-quotedpython3 -cargument:python latest=int('$LATEST',16)Shell expansion occurs before Python parses this source. A malicious
resultvalue containing quote characters and Python syntax can terminate the intended string literal and introduce additional executable statements. Consequently, a read-only network query can become arbitrary local Python execution.This behavior is not necessary for the skill's declared blockchain-query functionality and violates least-privilege principles. The block-range calculation can be performed while treating the RPC value strictly as data.
The pre-scan warning concerning a
curl | bashremote-script pipeline was not confirmed. The audited files contain direct JSON-RPCcurlrequests, not remote shell-script execution. The vulnerability instead arises from unsafe interpolation of one response into a later Python program.Attack Path
- An attacker compromises, impersonates, or otherwise controls the con ...[truncated 1171 chars]
- Remediation
View remediation
Remediation Suggestions
Treat the RPC result as data rather than interpolating it into source code:
- Validate that the value is a string matching the strict pattern
0x[0-9a-fA-F]+. - Pass the value through an environment variable, standard input, or a positional argument.
- Keep the Python program in a single-quoted shell string so shell expansion cannot modify its source.
- Fail closed when JSON parsing, type checking, or hexadecimal validation fails.
- Prefer parsing the response and calculating the range in one process to minimize trust-boundary crossings.
One hardened approach is:
bash FROM_HEX=$( curl -fsSL -X POST https://mainnet.qelt.ai \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' | python3 -c ' import json import re import sys response = json.load(sys.stdin) value = response.get("result") if not isinstance(value, str) or re.fullmatch(r"0x[0-9a-fA-F]+", value) is None: raise SystemExit("Invalid block number returned by RPC endpoint") print(hex(max(0, int(value, 16) - 1000))) ' )This version never inserts the remote value into executable source and rejects malformed or malicious responses before conversion.
- Validate that the value is a string matching the strict pattern
