Back to skill

Security audit

中国天气

Security checks for vulnerabilities and agentic risk

Overview

This is a normal China weather lookup skill, but its local cache and network handling create review-worthy security risks.

Review before installing. The skill appears intended for weather lookup rather than abuse, but it runs a local shell script, sends city names to wttr.in, uses unsecured request URLs, and stores cached results in a shared temporary directory. Prefer a version that uses HTTPS and a private user-owned cache directory.

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

Warning
Location
scripts/weather.sh:7
Finding

Predictable Shared Temporary Cache Allows Symlink-Based File Overwrite

Content
View full analysis
/dev/null || stat -c %Y "$cache_file" 2>/dev/null || echo "0") local age=$((now - mtime)) if [[ $age -lt $CACHE_TTL ]]; then cat "$cache_file" return 0 fi fi return 1 } set_cache() { local key="$1" local data="$2" echo "$data" > "$CACHE_DIR/${key}.cache" } ``` ### Technical Analysis The script stores cache files in a fixed, predictable directory under the globally shared `/tmp` namespace. It creates that directory with `mkdir -p` but does not verify its owner, type, or permissions. If the directory already exists, the script accepts it without validation. Cache filenames are also predictable, and `set_cache` writes to them using ordinary shell redirection. Shell redirection follows symbolic links. Consequently, a local attacker can prepare a cache filename as a symbolic link to another file before the Skill writes its response. The vulnerability does not bypass operating-system file permissions: the target must be writable by the user running the Skill. However, if the Skill is invoked by a different or more privileged account, the write occurs with that account's privileges. ### Attack Path 1. A local attacker creates `/tmp/china-weather-cache` before the victim runs the Skill and configures it so the victim can write into it. 2. The attacker predicts the cache filename for a city, such as `current_beijing.cache`. 3. The attacker creates that path as a symbolic link to a file writ ...[truncated 1103 chars]
Remediation
View remediation
&2 exit 1 fi set_cache() { local key="$1" local data="$2" local target="$CACHE_DIR/${key}.cache" local temporary [[ ! -L "$target" ]] || return 1 temporary=$(mktemp "$CACHE_DIR/.cache.XXXXXX") || return 1 printf '%s\n' "$data" > "$temporary" mv -f -- "$temporary" "$target" } ``` Cache keys should additionally be generated from a collision-resistant encoding or digest of the complete normalized city value. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/weather.sh:133
Finding

Weather Queries Are Sent over Unencrypted HTTP

Content
View full analysis
/dev/null | head -10 } get_week() { local city="$1" curl -s --max-time 10 "wttr.in/${city}?format=v2" 2>/dev/null } get_detailed() { local city="$1" curl -s --max-time 10 "wttr.in/${city}?0" 2>/dev/null } ``` The same scheme-less URL pattern also appears in current-weather and lifestyle-index requests at lines 120 and 152. ### Technical Analysis The `curl` URLs omit an explicit scheme. Curl interprets these HTTP-style host paths using plaintext HTTP rather than enforcing HTTPS. The script therefore provides no transport confidentiality, server authentication, or response integrity for the weather requests. A network-adjacent or on-path attacker can observe the requested city and modify the response before it reaches the script. Because output from the service is displayed directly, and current-weather output can be cached, forged information may be presented to the user as legitimate weather data. The returned content is not evaluated as shell code, so the reviewed implementation does not turn response tampering into direct code execution. ### Attack Path 1. A user invokes the script with a city and weather command. 2. The script sends the request to `wttr.in` without HTTPS protection. 3. An attacker controlling an intermediary network, gateway, proxy, or similarly privileged network position intercepts the request. 4. The attacker learns the queried location and can replace the server response with forged weather information. 5. The script prints the modified response. For current-weather requests, it may also store the forged response in the local cache for subsequent use. ### Impact Assessment The vulnerability exposes queried city information to ...[truncated 415 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The script mostly aligns with the general weather-query purpose: it fetches current weather and forecast data for Chinese cities via wttr.in and supports Chinese city names. However, there are material description/behavior mismatches. First, the description explicitly says it supports querying by city name or city code, but the code only handles city names/English names and contains no city-code resolution logic. Second, the '生活指数' feature is described as if it provides meaningful weather-derived advice, but the implementation outputs fixed canned recommendations and only appends current temperature/humidity, so it does not truly compute or fetch real indices. Third, the code includes an additional 'alert' capability using a QWeather API key, which is not declared in the description or permissions. While this alert function is mostly a stub, it still represents undeclared external-service behavior. Overall, the primary purpose is weather lookup, but the description does not accurately represent several important implementation details.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill documents direct shell execution but does not declare any explicit tool scope or permissions, so an agent may invoke shell capabilities without clear policy boundaries. In a skill ecosystem, missing scope declarations weaken least-privilege controls and make later script changes harder to govern or audit safely.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

User-facing comments, help text, command descriptions, and error messages are all in Chinese, and the skill presents itself as a China weather tool without offering an opt-in language selection. The policy requires avoiding forced language or locale constraints unless they are explicitly justified or optional.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest explicitly states '支持城市名或城市代码查询', implying users can query by city code. The implementation only normalizes Chinese city names to English names/pinyin and otherwise passes the input directly to wttr.in; there is no code path, mapping, or API usage for resolving or validating Chinese weather city codes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script sends user-supplied city queries to the external service wttr.in without disclosing that data leaves the local environment. While the transmitted data is low sensitivity in this skill context, undisclosed third-party data transfer is still a privacy weakness and may violate user expectations or policy requirements.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The inline comment '# 获取气象预警' and help text present 'alert' as a real feature, but the function only checks for an environment variable, prints configuration instructions, and otherwise outputs '暂无预警信息' without making any network request or performing an alert lookup. This is an active contradiction between documented intent and actual behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.