T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/fetch_tase_data.sh:36
- Finding
- User-Controlled Ticker Permits jq Filter Injection## Vulnerability Details **File Location**: `scripts/fetch_tase_data.sh`, lines 36-45 **Vulnerability Type**: Dynamic jq program construction using untrusted input **Risk Level**: High ### Vulnerable Code ```sh echo "$result" | jq '{ source: "Finnhub", ticker: "'$ticker'", price: .c, high: .h, low: .l, open: .o, volume: .v, currency: "ILS" }' ``` ### Technical Analysis The user-controlled `$ticker` value is concatenated directly into a `jq` filter rather than supplied as a data argument. Although shell quoting limits direct shell metacharacter interpretation, quotation marks and valid jq syntax within the ticker can terminate the intended string and alter the jq program. A crafted ticker can inject jq expressions that manipulate the generated response or access jq features such as `$ENV`, which exposes environment variables inherited by the jq process. This may allow disclosure of `FINNHUB_API_KEY` and other secrets present in the script's environment. This is jq-language injection rather than direct shell-command injection. The demonstrated scope is response manipulation, environment-variable disclosure, and processing disruption; the affected code does not establish arbitrary operating-system command execution. ### Attack Path 1. An attacker supplies a specially crafted ticker or security identifier to the Skill. 2. The Skill invokes `fetch_tase_data.sh` with the attacker-controlled value. 3. The script normalizes the identifier but does not restrict it to a safe ticker character set. 4. A successful Finnhub response reaches the vulnerable jq operation. 5. The ticker is inserted into the jq filter as executable syntax. 6. The injected expression accesses `$ENV`, changes the output structure, or causes the filter to fail. 7. Sensitive environment values or attacker-controlled output may be printed and subsequently returned by the Agent. ### Impact Assessment An ...[truncated 515 chars]
- Remediation
- ## Remediation Suggestions Pass the ticker to jq as data with `--arg` rather than concatenating it into jq source: ```sh echo "$result" | jq --arg ticker "$ticker" '{ source: "Finnhub", ticker: $ticker, price: .c, high: .h, low: .l, open: .o, volume: .v, currency: "ILS" }' ``` Apply the same pattern to every jq invocation and construct fallback JSON with `jq -n --arg` rather than interpolated shell strings. Validate ticker input before any network request or structured-data processing. For example, permit only the character set and length required by supported identifiers: ```sh if [[ ! "$TICKER" =~ ^[A-Z0-9._-]{1,32}$ ]]; then echo '{"error":"Invalid ticker format"}' exit 1 fi ``` Additional hardening should include: - Invoke the Python implementation instead of maintaining a separate dynamically constructed jq path. - Run the script with a minimal environment containing only required variables. - Add regression tests using quotation marks, jq operators, Unicode input, and malformed identifiers. - Ensure error output cannot accidentally include inherited environment variables.
