Back to skill

Security audit

中国城市天气Weather in China

Security checks for vulnerabilities and agentic risk

Overview

This Chinese weather skill is mostly coherent, but its shell script evaluates weather data fetched from the internet as shell code, creating a real command-execution risk.

Review before installing. The tool only needs city weather lookup, but it should remove eval and treat fetched HTML as untrusted text before routine use. Install only if you are comfortable running a shell script that queries weather.com.cn and after the command-injection issue is fixed.

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 (1)

T09 · Insecure Skill Coding Practices

Error
Location
weather-cn.sh:40
Finding

Remote Command Injection Through Evaluation of Untrusted Weather Data

Content
View full analysis

Vulnerability Details

File Location: weather-cn.sh, lines 40–48, 63–72, 123–128, and 133–139
Vulnerability Type: Shell command injection through eval
Risk Level: High

Vulnerable Code

bash
fetch_weather() {
    local city_code="$1"
    local url="https://www.weather.com.cn/weather/${city_code}.shtml"

    # Fetch HTML content
    local html
    html=$(curl -s --max-time 10 "$url" 2>/dev/null)

    if [ -z "$html" ]; then
        error "Unable to retrieve weather data"
    fi

    echo "$html"
}
bash
# Extract weather information from the remote HTML title
local weather
weather=$(cat "$tmpfile" | grep -o '<title>[^<]*</title>' | sed 's/<title>//' | sed 's/天气预报.*//' | head -1)

# If unavailable in the title, extract it from the HTML body
if [ -z "$weather" ] || [ "$weather" = "未知" ]; then
    weather=$(cat "$tmpfile" | grep -oE '(晴转多云|多云转晴|晴|多云|阴|小雨|大雨|雪|雷阵雨)' | head -1)
fi
bash
echo "WEATHER=${weather:-未知}"
echo "TEMP=${temp:-未知}"
echo "COLD_INDEX=${cold_index}"
echo "SPORT_INDEX=${sport_index}"
echo "DRESS_INDEX=${dress_index}"
echo "WASH_INDEX=${wash_index}"
echo "UV_INDEX=${uv_index}"
bash
format_output() {
    local city="$1"
    shift
    local data="$@"

    # Parse data
    eval "$data"

Technical Analysis

The script downloads HTML from an external website and extracts the weather description from the remotely controlled <title> element. The extracted value is serialized into a shell assignment such as WEATHER=<remote content>. The resulting multiline string is then passed directly to eval.

eval parses its input as shell source code rather than treating it as inert data. The remote weather value is neither shell-escaped nor constrained to an allowlist before evaluation. Consequently, shell metacharacters, command substitutions, assignment-breaking syntax, or additional commands embedded in the res ...[truncated 2339 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove eval completely. Do not serialize parsed values as shell source code. Pass each value as a quoted function argument, store values in global variables, or use another data-transfer mechanism that does not invoke a shell parser.

    A safer design is:

    bash
    format_output "$city" "$weather" "$temp" \
        "$cold_index" "$sport_index" "$dress_index" \
        "$wash_index" "$uv_index"
    

    The receiving function should assign each positional parameter with quoting:

    bash
    format_output() {
        local city="$1"
        local weather="$2"
        local temp="$3"
        local cold_index="$4"
        local sport_index="$5"
        local dress_index="$6"
        local wash_index="$7"
        local uv_index="$8"
        # Format values without eval.
    }
    
  2. Strictly validate remote values. Restrict weather descriptions and temperatures to the precise formats needed by the application. Prefer selecting known weather terms rather than accepting arbitrary title text. Reject unexpected control characters, newlines, quotes, backticks, dollar signs, semicolons, parentheses, and other shell syntax as defense in depth.

  3. Treat all network responses as untrusted. Keep remote data quoted at every use and never interpret it as executable shell syntax, even when obtained over HTTPS.

  4. Harden the HTTP request. Use options such as:

    bash
    curl --fail --silent --show-error --max-time 10 \
         --max-filesize 1048576 "$url"
    

    Also validate the response type and impose a reasonable response-size limit.

  5. Avoid unnecessary temporary-file handling. Parse data directly from standard input where practical. If a temporary file remains necessary, create it with mktemp, ensure cleanup with a trap, and maintain restrictive permissions:

    bash
    tmpfile=$(mktemp) || exit 1
    trap 'rm -f "$tmpfile"' RETURN
    

...[truncated 250 chars]

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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The document title and all usage instructions are written entirely in Chinese, which imposes a specific language on users without any opt-in or alternative. Under the policy, language constraints should either offer a choice or be clearly documented as a justified region-specific limitation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises executable shell usage via direct script and curl examples, but it does not declare any explicit tool scope such as allowed shell access or restricted permissions. This creates an authorization and review gap: an agent may invoke shell-capable behavior without a clearly documented boundary, increasing the chance of unintended command execution or overbroad runtime privileges.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The description labels this as a Chinese weather tool and the document emphasizes "原生中文", but it does not state that language choice is optional or limited to a China-specific compliance/business need. This can violate language/locale policy when a skill forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

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

方案2:Open-Meteo API

bash
curl -s "https://api.open-meteo.com/v1/forecast?latitude=39.9042&longitude=116.4074&current_weather=true&daily=temperature_2m_max,temperature_2m_min,weathercode&timezone=Asia%2FShanghai"

方案3:wttr.in

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation examples are very broad and match ordinary weather-related conversation, so the skill may trigger in situations the user did not intend. Overbroad triggering can cause unwanted network access or shell execution and can override a more appropriate native assistant response path.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script description and all user-facing messages are in Chinese, and the usage implies a Chinese-only interaction model. Under the policy rule, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The script makes an outbound HTTP request to weather.com.cn using data derived from the user's requested city, but there is no user-facing notice at the time of the request beyond implementation comments. For code files, network calls that transmit user or system data should have some visible disclosure such as a prompt, print/log message, or documented warning.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This plain-text file uses Chinese-only natural language in its heading and format description, which may imply a fixed language/locale without any opt-in or justification. Under the policy rule, forcing a specific language can be a violation unless the locale constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.