Back to skill

Security audit

Weather Pet Forecast

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent pet-weather helper, but its runtime instructions use unsafe shell commands with user-provided locations.

Review before installing. This skill should use a safe HTTP client or wrapper that URL-encodes locations, enforces HTTPS, validates response size and schema, and clearly warns users before sending their location to wttr.in.

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
SKILL.md:35
Finding

Shell Command Injection Through Unvalidated Location Substitution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 35-40
Vulnerability Type: Shell command injection through user-controlled template substitution
Risk Level: High

Vulnerable Code

bash
# JSON format for parsing (recommended)
curl -s "wttr.in/{LOCATION}?format=j1"

# Human-readable 3-day forecast
curl -s "wttr.in/{LOCATION}"

Technical Analysis

The documented workflow accepts a location supplied by the user and instructs the agent to insert it directly into a shell command. Enclosing the URL in double quotes does not prevent shell expansions such as command substitution using $(...) or backticks.

If the agent replaces {LOCATION} verbatim and invokes the resulting command through a shell, a crafted location can cause local commands to execute before curl runs. Network access is necessary for the Skill, but executing a shell command constructed from untrusted location text is not necessary and exceeds the minimum safe implementation requirements.

Attack Path

  1. An attacker supplies a location containing shell syntax, such as $(attacker_command).
  2. The agent substitutes that value directly for {LOCATION} in the documented command.
  3. The command is passed to a shell.
  4. The shell evaluates the command substitution despite the surrounding double quotes.
  5. The attacker's command executes locally, after which curl processes the resulting URL.

Exploitation depends on the calling agent performing literal template substitution and executing the generated string through a shell.

Impact Assessment

Successful exploitation provides arbitrary command execution with the same operating-system privileges as the agent or user running the Skill. Depending on those privileges and the host environment, this could permit reading or modifying accessible files, accessing environment variables or credentials, making unauthorized network requests, tampering with project data, or ex ...[truncated 124 chars]

Remediation
View remediation

Remediation Suggestions

  • Do not construct shell command strings by interpolating user-controlled location values.
  • Prefer an HTTP client API that accepts the endpoint and query parameters separately and does not invoke a shell.
  • If curl must be used, invoke it as an argument array rather than through shell evaluation.
  • Validate locations against a narrowly defined character set and length limit appropriate for city names, country names, and airport codes.
  • URL-encode the location as data rather than concatenating it into the URL.
  • Reject shell metacharacters and control characters as defense in depth.
  • Update the documentation to provide a safe wrapper that receives the location as a positional argument and performs URL encoding internally.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/test_cities.sh:17
Finding

Weather Data Retrieved Over Unauthenticated HTTP

Content
View full analysis

Vulnerability Details

File Locations:

  • SKILL.md, lines 35-40, 150-177, and 241-246
  • scripts/test_cities.sh, line 17
  • scripts/test_round2.sh, line 15

Vulnerability Type: Cleartext network transport and missing server-response enforcement
Risk Level: Medium

Vulnerable Code

SKILL.md, lines 35-40:

bash
# JSON format for parsing (recommended)
curl -s "wttr.in/{LOCATION}?format=j1"

# Human-readable 3-day forecast
curl -s "wttr.in/{LOCATION}"

SKILL.md, lines 241-246:

bash
# English output (for English queries)
curl -s "wttr.in/Tokyo?format=j1" | python3 scripts/weather_analysis.py "Tokyo" --lang en

# Chinese output (for Chinese queries)
curl -s "wttr.in/Beijing?format=j1" | python3 scripts/weather_analysis.py "Beijing" --lang zh

scripts/test_cities.sh, line 17:

bash
result=$(curl -s --max-time 15 "wttr.in/$city?format=j1" 2>&1)

scripts/test_round2.sh, line 15:

bash
result=$(curl -s --max-time 20 --retry 2 --retry-delay 3 "wttr.in/$city?format=j1" 2>&1)

Technical Analysis

All listed URLs omit an explicit https:// scheme. With curl, these values are treated as HTTP URLs, causing the initial request to use an unauthenticated cleartext transport. The commands also use silent mode without --fail, HTTPS-only protocol restrictions, or explicit TLS requirements.

A network-positioned attacker can intercept or alter the response. The Python parser treats structurally valid weather JSON as trusted input and incorporates remote fields, including weather descriptions and location-related data, into its generated Markdown output.

The flagged pipelines do not download and execute remote shell or Python source code. They pipe weather JSON into the bundled local parser, so the evidence does not support classification as remote payload retrieval and execution. The actual risk is transport integrity and trust in attacker-m ...[truncated 1205 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace every endpoint with an explicit HTTPS URL, such as https://wttr.in/....

  • Require encrypted transport and reject protocol downgrades:

    bash
    curl --fail --silent --show-error \
      --proto '=https' \
      --tlsv1.2 \
      "https://wttr.in/Beijing?format=j1"
    
  • Use --location only if redirects are required, and combine it with --proto-redir '=https' so redirects cannot downgrade to HTTP.

  • Fail closed on HTTP errors and empty or malformed responses.

  • Apply reasonable connection, total-time, response-size, and retry limits.

  • Validate the response schema and expected field types before analysis.

  • Escape untrusted service-provided strings before embedding them into Markdown or another downstream rendering context.

  • Apply the HTTPS-only change consistently in SKILL.md, scripts/test_cities.sh, and scripts/test_round2.sh.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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
Findings (10)

External Script Fetching

High
Category
Supply Chain
Confidence
97% confidence
Finding

The skill instructs use of shell-based curl against an external service with a user-controlled location substituted into the URL. Even though quoted, this normalizes shell execution and external retrieval inside the skill, creating risk from command misuse, URL manipulation, SSRF-style access patterns through tooling, and unreviewed remote content ingestion.

Content

Scanner excerpt · SKILL.md (reported line 37)May include surrounding context.

bash
# JSON format for parsing (recommended)
curl -s "wttr.in/{LOCATION}?format=j1"

# Human-readable 3-day forecast
curl -s "wttr.in/{LOCATION}"

External Script Fetching

High
Category
Supply Chain
Confidence
98% confidence
Finding

Piping remote network data directly into a local Python script creates a strong trust boundary violation: untrusted external content becomes stdin to executable code. If the script is fragile or later modified unsafely, this pattern can lead to code/logic exploitation, parser abuse, or harmful agent actions based on maliciously crafted upstream responses.

Content

Scanner excerpt · SKILL.md (reported line 246)May include surrounding context.

curl -s "wttr.in/Tokyo?format=j1" | python3 scripts/weather_analysis.py "Tokyo" --lang en

Chinese output (for Chinese queries)

curl -s "wttr.in/Beijing?format=j1" | python3 scripts/weather_analysis.py "Beijing" --lang zh

text

**Language Options:**

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

The script fetches untrusted data from an external service (wttr.in) and pipes it directly into a local Python program for processing. Although it does not execute the fetched content as shell code, this creates a trust boundary issue: a compromised, spoofed, or malicious remote response could trigger unsafe behavior in weather_analysis.py, leak data through logs, or cause denial of service if the parser is not robust. In the skill context, this is somewhat expected functionality for weather retrieval, but it still increases risk because network-supplied content is consumed without validation or integrity checks.

Content

Scanner excerpt · scripts/test_cities.sh (reported line 17)May include surrounding context.

sh
echo "Testing: $city (lang: $lang)"
    
    while [ $retry -lt $max_retries ]; do
        result=$(curl -s --max-time 15 "wttr.in/$city?format=j1" 2>&1)
        
        if [ $? -eq 0 ] && [ -n "$result" ]; then
            echo "$result" | python3 "$SCRIPT" "$city" --lang "$lang" 2>&1

External Script Fetching

High
Category
Supply Chain
Confidence
90% confidence
Finding

Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Content

Scanner excerpt · scripts/test_round2.sh (reported line 15)May include surrounding context.

sh
local result=""
    
    while [ $retry -lt $max_retries ]; do
        result=$(curl -s --max-time 20 --retry 2 --retry-delay 3 "wttr.in/$city?format=j1" 2>&1)
        
        if [ $? -eq 0 ] && [ -n "$result" ] && echo "$result" | python3 -c "import sys, json; json.load(sys.stdin)" 2>/dev/null; then
            echo "$result" | python3 "$SCRIPT" "$city" --lang "$lang"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill invokes shell/network capabilities via curl and local script execution but does not declare an explicit tool scope such as allowed-tools or permissions. This creates a capability mismatch that can cause the agent to execute commands the user did not reasonably expect, reducing governance and increasing the chance of unsafe tool use.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill description is broad enough to capture generic weather requests, not just pet-focused forecasting. Over-broad routing can unnecessarily activate a skill that transmits location externally and uses shell commands, increasing privacy and tool-exposure risk in situations where a simpler built-in response would suffice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The workflow instructs sending user-provided location data to wttr.in without any user-facing disclosure or consent step. Location can be sensitive personal data, and transmitting it to a third-party service without warning creates a privacy risk and may violate platform data-handling expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The language section states that for 'Other languages' the skill should default to English. This imposes a specific language for users who did not ask for English and does not offer a language choice or opt-in, which is a natural-language policy issue under the locale/language rule.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The invocation guidance lists positive examples but does not define boundaries or negative examples, so the skill may be selected for common weather questions unrelated to pets. That increases unnecessary data sharing and external tool usage, though the direct security impact is limited compared with code execution issues.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script defaults the language parameter to English (en) and later hard-codes test runs in English and Chinese. This imposes specific locales without offering the user a choice or documenting why these locales are required, which matches the language/locale policy violation category.

Content

No source excerpt is available for this finding.