Back to skill

Security audit

全国天气预报查询 - 聚合数据

Security checks for vulnerabilities and agentic risk

Overview

This weather skill does what it claims, but it sends the user’s API key and city query over unencrypted HTTP, which can expose the credential and query data.

Review before installing. Use an environment variable for JUHE_WEATHER_KEY rather than scripts/.env or --key, and do not use this skill with a valuable production API key unless the endpoints are changed to HTTPS. Be aware that city names you query are sent to Juhe and, in the current script, may be visible to network observers.

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
scripts/weather.py:22
Finding

API Credential and Query Data Transmitted over Plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: scripts/weather.py:22-23 and scripts/weather.py:70-73
Vulnerability Type: Plaintext transmission of sensitive information
Risk Level: High

Vulnerable Code

python
WEATHER_API_URL = "http://apis.juhe.cn/simpleWeather/query"
LIFE_API_URL = "http://apis.juhe.cn/simpleWeather/life"
python
def _request(url: str, params: dict) -> dict:
    """发起 HTTP GET 请求"""
    full_url = f"{url}?{urllib.parse.urlencode(params, encoding='utf-8')}"
    try:
        with urllib.request.urlopen(full_url, timeout=15) as resp:
            return json.loads(resp.read().decode("utf-8"))
    except Exception as e:
        return {"error_code": -1, "reason": f"网络请求失败: {e}"}

Technical Analysis

The weather and lifestyle API endpoints use unencrypted HTTP. The _request function includes the Juhe API key and the user-supplied city in the URL query string before transmitting the request.

Although sending an API credential to the declared weather provider is necessary for the Skill's functionality, sending it without transport encryption is not necessary and violates least-risk handling of credentials. Any party able to observe or modify traffic between the host and the API server—including a local-network attacker, compromised gateway, ISP-level observer, or malicious proxy—can read the API key and city value.

Placing the credential in a URL also increases exposure because complete URLs may be retained in proxy logs, access logs, network monitoring systems, or diagnostic records.

Attack Path

  1. A user configures a valid API key through JUHE_WEATHER_KEY, scripts/.env, or the --key argument.
  2. The user invokes the script with a city name.
  3. The script constructs a URL such as: http://apis.juhe.cn/simpleWeather/query?key=API_KEY&city=CITY
  4. The complete URL is transmitted over plaintext HTTP.
  5. An attacker with network visibility ca ...[truncated 883 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace both plaintext endpoints with provider-supported HTTPS endpoints:

    python
    WEATHER_API_URL = "https://apis.juhe.cn/simpleWeather/query"
    LIFE_API_URL = "https://apis.juhe.cn/simpleWeather/life"
    
  2. Ensure requests never fall back or redirect to HTTP. Validate the final response URL and reject any non-HTTPS scheme.

  3. If supported by the provider, transmit the API key in an authorization header or POST body instead of the query string to reduce exposure in URL logs.

  4. Update the direct-call examples in SKILL.md:102-107 to use HTTPS exclusively.

  5. Prefer the environment variable or a permission-restricted secret file for key configuration. Deprecate the --key option because command-line arguments can be exposed through shell history and process listings.

  6. Rotate any API key that has previously been used through the current HTTP implementation, because it may already have been exposed.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
Findings (10)

Credential Access

High
Category
Privilege Escalation
Confidence
93% confidence
Finding

The skill instructs users to place the API key into scripts/.env and also supports passing the key on the command line. Storing secrets in a workspace file risks accidental exposure through file reads, commits, backups, or logs, and CLI arguments may be exposed via shell history or process listings.

Content

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

md
# 方式一:环境变量(推荐)
export JUHE_WEATHER_KEY=你的AppKey

# 方式二:.env 文件
echo "JUHE_WEATHER_KEY=你的AppKey" > scripts/.env

# 方式三:命令行传入

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The explicit command that writes JUHE_WEATHER_KEY to scripts/.env normalizes insecure secret handling inside the repository tree. In an agent environment with file-read capability, this materially increases the chance that the credential is discovered, exfiltrated, or unintentionally included in outputs.

Content

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

md
export JUHE_WEATHER_KEY=你的AppKey

# 方式二:.env 文件
echo "JUHE_WEATHER_KEY=你的AppKey" > scripts/.env

# 方式三:命令行传入
python scripts/weather.py --key 你的AppKey 北京

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/weather.py (reported line 12)May include surrounding context.

python
API Key 配置(任选其一,优先级从高到低):
    1. 环境变量: export JUHE_WEATHER_KEY=your_api_key
    2. 脚本同目录的 .env 文件: JUHE_WEATHER_KEY=your_api_key
    3. 直接传参: python weather.py --key your_api_key 北京

免费申请 API Key: https://www.juhe.cn/docs/api/id/73

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/weather.py (reported line 192)May include surrounding context.

python
API Key 配置(任选其一,优先级从高到低):
    1. 环境变量: export JUHE_WEATHER_KEY=your_api_key
    2. 脚本同目录的 .env 文件: JUHE_WEATHER_KEY=your_api_key
    3. 直接传参: python weather.py --key your_api_key 北京

免费申请 API Key: https://www.juhe.cn/docs/api/id/73

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/weather.py (reported line 52)May include surrounding context.

python
if env_key:
        return env_key

    env_file = Path(__file__).parent / ".env"
    if env_file.exists():
        for line in env_file.read_text(encoding="utf-8").splitlines():
            line = line.strip()

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill documents access to environment variables, local files (.env), and outbound network calls, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates an authorization ambiguity where an agent may invoke capabilities broader than users or reviewers expect, increasing the chance of unintended data access or network use.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger examples are broad enough that the skill could activate on generic phrases like '天气预报' or '生活指数' without clear constraints or disambiguation. Overbroad activation can cause the agent to invoke external calls unexpectedly, potentially sending user-provided location queries to a third-party service when the user did not intend to use this specific skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The natural-language description, examples, and AI usage guidance assume Chinese-only interaction and city extraction from Chinese inputs, but do not state that the skill is intentionally limited to a Chinese-speaking or China-specific context. Under the language/locale policy, a forced locale should be opt-in or clearly justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script sends the API key and city name to third-party endpoints over plain HTTP, so the full request can be intercepted or modified by any attacker on the network path. Because the API key is placed in the URL query string, it is especially exposed to eavesdropping, logging, and replay.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

Natural-language content in the docstring is exclusively Chinese, and later usage and error messages are also presented only in Chinese. This imposes a locale/language choice on users without offering an alternative or opt-in, which matches the language policy violation criteria.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.