Back to skill

Security audit

Israeli Stock Analysis

Security checks for vulnerabilities and agentic risk

Overview

The skill is broadly aligned with Israeli stock analysis, but its shell helper has real credential-exposure risks and the investment-recommendation guidance needs caution.

Review this skill before installing if you plan to use API keys. Prefer the Python fetcher over the shell script, run it with a minimal environment, and treat generated Buy/Hold/Sell outputs as informational analysis rather than personal financial advice.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

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.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/fetch_tase_data.sh:31
Finding
Finnhub API Key Exposed in curl Command-Line Arguments## Vulnerability Details **File Location**: `scripts/fetch_tase_data.sh`, lines 31-32 **Vulnerability Type**: Sensitive credential exposure through process arguments **Risk Level**: Medium ### Vulnerable Code ```sh if [[ -n "$FINNHUB_API_KEY" ]]; then local result=$(curl -s "https://finnhub.io/api/v1/quote?symbol=${ticker}&token=${FINNHUB_API_KEY}") ``` ### Technical Analysis The Finnhub API key is embedded directly in curl's URL argument. While transmission to the fixed Finnhub HTTPS endpoint is necessary for the declared market-data functionality, placing the credential in a command-line argument can expose it outside the intended network transaction. Depending on operating-system and container isolation settings, command-line arguments may be visible through process-inspection interfaces, monitoring agents, diagnostic tooling, audit systems, or process telemetry. Query strings may also be captured by proxy and HTTP diagnostic logs. HTTPS protects the request while it is in transit but does not prevent local process-list or logging exposure. ### Attack Path 1. The user configures `FINNHUB_API_KEY` in the execution environment. 2. A quote request invokes `fetch_tase_data.sh`. 3. The script expands the key into curl's URL argument. 4. While curl is running, a local process-monitoring mechanism or another sufficiently permitted process reads or records its command line. 5. The observer extracts the `token` query parameter. 6. The exposed key can be reused to make requests against the user's Finnhub account or quota. ### Impact Assessment Exposure can allow unauthorized consumption of the user's Finnhub API quota and access to provider functionality granted by the key. It may also lead to account disruption or billing consequences depending on the associated service plan. This issue does not independently provide system privilege escalation. The practical scope depends on local process visibility, logg ...[truncated 86 chars]
Remediation
## Remediation Suggestions Prefer an authentication header if Finnhub supports one for this endpoint. This keeps the secret out of the URL and reduces query-string logging: ```sh curl --silent --show-error \ --header "X-Finnhub-Token: ${FINNHUB_API_KEY}" \ --get \ --data-urlencode "symbol=${ticker}" \ "https://finnhub.io/api/v1/quote" ``` If query-parameter authentication is mandatory: - Use a client mechanism or protected configuration that avoids exposing the expanded secret in process arguments. - Ensure proxy, application, shell-tracing, and monitoring logs redact the `token` parameter. - Disable shell tracing before handling credentials. - Execute the script in an environment that prevents unrelated users from inspecting its processes. - Use a least-privilege, revocable API key and rotate it if exposure is suspected. - Avoid printing full request URLs in errors or diagnostics. - Consider standardizing on the Python client path, which does not place the expanded URL in a separate curl process argument.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (11)

Tainted flow: 'url' from os.getenv (line 85, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
try:
        url = f"https://finnhub.io/api/v1/quote?symbol={ticker}&token={api_key}"
        with urllib.request.urlopen(url, timeout=5) as response:
            data = json.loads(response.read().decode())
            
            return {
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'url' from os.getenv (line 85, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
try:
        url = f"https://finnhub.io/api/v1/quote?symbol={ticker}&token={api_key}"
        with urllib.request.urlopen(url, timeout=5) as response:
            data = json.loads(response.read().decode())
            
            return {
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description promises an end-user analysis skill with broad analytical capabilities for Israeli stocks. The actual code is only a helper script for fetching quote data and scaffolding placeholder responses for fundamental/technical sections. Its primary purpose is data retrieval/normalization, not analysis. There is no evidence of financial metric computation, technical indicator calculation, support/resistance or chart pattern detection, stock-to-stock comparison, valuation, report generation, or recommendation logic. While Hebrew names and ETF numbers are partially supported through small hardcoded mappings, that only covers a minor subset of the declared functionality. Therefore the description materially overstates what the code actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description promises a broad stock-analysis skill for TASE securities, covering fundamental and technical analysis, comparisons, and report generation in Hebrew and English. This code chunk does not implement those capabilities. Its actual scope is narrow: it converts/normalizes tickers, handles two hardcoded ETF/index mappings, and fetches price quote data from external market-data APIs. The script only supports the 'price' data type and explicitly says other types should use a different Python script. While quote retrieval is a plausible supporting component of a larger stock-analysis skill, this specific supplied code chunk materially underdelivers relative to the declared purpose and behaves primarily as a market-data fetcher, not a comprehensive analysis engine.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
- If query mixes languages, respond in the language of the primary request
- Always clarify company/ticker names in both languages

## Output Guidelines

**General Principles:**
- Use tables for financial data and comparisons (easy to scan)
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill explicitly instructs use of bundled scripts, direct API calls, MCPs, environment variables, curl, and web/network fetching, yet it declares no tool scope or permissions. That creates an over-privileged or ambiguously privileged execution model where an agent may invoke shell, network, or environment access without an explicit allowlist, increasing the chance of unsafe tool use or data exposure.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill directs the agent to generate Buy/Hold/Sell recommendations, target prices, conviction levels, and entry strategies without requiring a prominent warning that this is informational content rather than professional financial advice. In a financial-analysis context, that increases the risk of harmful or noncompliant guidance, especially if users rely on outputs as personalized investment advice.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The template instructs the writer to provide the company description "in Hebrew and English if mixed language," which introduces a language-format requirement without indicating that the user can choose their preferred language. This can conflict with organizational language/locale policies that require user choice or explicit opt-in.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This document provides detailed trading signals, entry/exit framing, stop-loss guidance, and risk/reward criteria without a clear disclaimer that technical analysis is educational information rather than personalized financial advice. In an investment-analysis skill, users may rely on these instructions to make real trades and suffer financial loss, especially given the added volatility and liquidity risks noted for TASE securities.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The instruction states that all valuations should be in ILS unless conversion is requested, which imposes a default locale/currency convention on the user. Under the policy, forcing a language or locale-specific format without explicit opt-in can be a natural-language policy concern unless clearly justified as region-specific.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The usage example includes a Hebrew company name and the hardcoded name-to-ticker mapping only supports Hebrew names. This creates a language-specific behavior in the natural-language interface without an explicit opt-in or a documented locale constraint, which fits the language/locale policy concern.

Static analysis

No suspicious patterns detected.