Back to skill

Security audit

Weather Ensemble Forecast

Security checks for vulnerabilities and agentic risk

Overview

This weather skill is mostly purpose-aligned, but its scripts can send an API key to an undocumented, configurable server instead of only the documented HTTPS service.

Review before installing. Use it only if you trust the Weather Ensemble API service, avoid setting WEATHER_ENSEMBLE_HOST, and treat WEATHER_ENSEMBLE_API_KEY as a credential that may be transmitted on each request. A safer version should pin or validate the HTTPS host before adding the API-key header.

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/forecast.sh:6
Finding
API Key Disclosure Through an Unrestricted Forecast API Host Override## Vulnerability Details **File Location**: `scripts/forecast.sh:6-22` **Vulnerability Type**: Credential disclosure through an attacker-controlled network destination **Risk Level**: High ### Vulnerable Code ```bash HOST="${WEATHER_ENSEMBLE_HOST:-https://polymarket-scanner.fly.dev}" API_KEY="${WEATHER_ENSEMBLE_API_KEY:-}" CITY="${1:?Usage: forecast.sh <city> [YYYY-MM-DD]}" CITY=$(echo "$CITY" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9 -]//g' | sed 's/ /%20/g') DATE=$(echo "${2:-}" | sed 's/[^0-9-]//g') CURL_ARGS=(-s -w "\n%{http_code}") if [ -n "$API_KEY" ]; then CURL_ARGS+=(-H "X-API-Key: $API_KEY") fi URL="${HOST}/forecast/${CITY}" if [ -n "$DATE" ]; then URL="${URL}?target_date=${DATE}" fi RESPONSE=$(curl "${CURL_ARGS[@]}" "$URL") ``` ### Technical Analysis The destination host is read from `WEATHER_ENSEMBLE_HOST` without validating its scheme, hostname, port, or embedded credentials. When `WEATHER_ENSEMBLE_API_KEY` is set, the script unconditionally attaches that secret to the resulting request as an `X-API-Key` header. Consequently, an environment value can redirect the request—and its API key—to an arbitrary server. Supplying an `http://` URL additionally permits plaintext credential transmission. This behavior exceeds the minimum network privilege required for the declared functionality, which only needs to contact `https://polymarket-scanner.fly.dev`. It also conflicts with the security statement in `SKILL.md`, which claims that all requests are sent to the named service via HTTPS. ### Attack Path 1. An attacker, compromised launcher, or unsafe runtime configuration sets `WEATHER_ENSEMBLE_HOST` to an attacker-controlled URL, such as `https://attacker.example`. 2. A legitimate credential is available through `WEATHER_ENSEMBLE_API_KEY`. 3. The user or Agent invokes the forecast command. 4. The script constructs the forecast URL from the attacker-controlled host. 5. ...[truncated 844 chars]
Remediation
## Remediation Suggestions 1. Remove `WEATHER_ENSEMBLE_HOST` from production execution and use a constant endpoint: ```bash readonly HOST="https://polymarket-scanner.fly.dev" ``` 2. If an override is genuinely required for development, validate the parsed destination before adding the API-key header. Require: - The `https` scheme. - The exact hostname `polymarket-scanner.fly.dev`. - No embedded username or password. - No unexpected port. - No redirection to a different origin. 3. Add restrictive curl options: ```bash curl --proto '=https' --tlsv1.2 --fail-with-body ... ``` 4. Disable redirects or ensure credentials are never forwarded across origins. If redirects are needed, validate every destination and do not use options such as `--location-trusted`. 5. Build the URL first, validate its origin, and only then append the `X-API-Key` header. 6. Update `SKILL.md` to accurately document any supported endpoint override and its security restrictions. 7. Add automated tests verifying that HTTP URLs, alternate domains, embedded credentials, and unexpected ports are rejected before any network request occurs.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/cities.sh:6
Finding
API Key Disclosure Through an Unrestricted Cities API Host Override## Vulnerability Details **File Location**: `scripts/cities.sh:6-14` **Vulnerability Type**: Credential disclosure through an attacker-controlled network destination **Risk Level**: High ### Vulnerable Code ```bash HOST="${WEATHER_ENSEMBLE_HOST:-https://polymarket-scanner.fly.dev}" API_KEY="${WEATHER_ENSEMBLE_API_KEY:-}" CURL_ARGS=(-s -w "\n%{http_code}") if [ -n "$API_KEY" ]; then CURL_ARGS+=(-H "X-API-Key: $API_KEY") fi RESPONSE=$(curl "${CURL_ARGS[@]}" "${HOST}/cities") ``` ### Technical Analysis The script accepts an arbitrary `WEATHER_ENSEMBLE_HOST` and does not enforce the documented HTTPS origin. When an API key is configured, it is sent to that unvalidated destination in the `X-API-Key` request header. An attacker who can influence the process environment can therefore redirect the cities request to a server they control and collect the credential. The override also accepts plaintext HTTP destinations, making interception possible on an untrusted network. This unrestricted override is unnecessary for the Skill's declared city-listing functionality, which only requires access to the documented Weather Ensemble API. ### Attack Path 1. An attacker or compromised runtime sets `WEATHER_ENSEMBLE_HOST` to a controlled endpoint, such as `http://attacker.example`. 2. The victim's `WEATHER_ENSEMBLE_API_KEY` remains present in the environment. 3. The user or Agent invokes the cities command. 4. The script requests `http://attacker.example/cities`. 5. The request includes the victim's API key in the `X-API-Key` header. 6. The attacker records the credential and can subsequently reuse it. Exploitation requires control of, or influence over, the Skill's environment or launch configuration. ### Impact Assessment The attacker can steal the Weather Ensemble API credential, make unauthorized requests under the victim's identity or quota, and potentially exhaust applicable service limits. Use of an HTT ...[truncated 324 chars]
Remediation
## Remediation Suggestions 1. Replace the configurable host with the fixed production API origin: ```bash readonly HOST="https://polymarket-scanner.fly.dev" ``` 2. If an override is required for testing, never send production credentials when it is active. Prefer a separate development script or explicit test-only credential. 3. Validate that the final endpoint uses HTTPS and exactly matches the approved hostname and port before attaching `X-API-Key`. 4. Restrict curl to HTTPS and modern TLS: ```bash curl --proto '=https' --tlsv1.2 --fail-with-body ... ``` 5. Prevent credentials from crossing origins through redirects. Keep redirects disabled unless every destination is independently validated. 6. Add regression tests that confirm arbitrary domains, plaintext HTTP, embedded URL credentials, and unexpected ports are rejected without transmitting the API key.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill is presented as a multi-model forecasting capability, but the file shows it is effectively a thin client to a remote backend (`polymarket-scanner.fly.dev`) that performs the actual work. This mismatch is dangerous because users and reviewers may trust local, transparent behavior while the real logic, data handling, and possible prompt or content manipulation occur on an opaque external service outside the declared description.

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill invokes shell scripts (`bash {baseDir}/scripts/forecast.sh` and `cities.sh`) but does not declare tool scope or allowed tools. This weakens the security boundary and reviewability of the skill, because an agent may execute code-capable actions without explicit permission metadata, increasing the chance of unintended command execution or hidden expansion of behavior in the referenced scripts.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger guidance says to run the skill whenever a user asks for weather forecasts, temperature predictions, model comparisons, or ensemble analysis, which is broad enough to cause unintended invocation. Over-broad routing can leak user queries and optional API keys to the remote service and can cause the agent to execute shell/network actions when a user did not specifically request this particular skill.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
This code conditionally reads a sensitive credential from the environment and sends it in an HTTP header to a remote host. The script has no confirmation prompt, user-facing notice, or inline warning explaining that it will transmit authentication material over the network.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script sends user-supplied city/date values and, if configured, an API key to a remote service endpoint without any in-file disclosure, consent prompt, or trust boundary validation. While remote API use is expected for a weather skill, the host is configurable via an environment variable and defaults to a third-party domain, which increases the risk of silent data exfiltration or credential leakage if the endpoint is changed or compromised.

Static analysis

No suspicious patterns detected.