Back to skill

Security audit

Lurefish

Security checks for vulnerabilities and agentic risk

Overview

This skill is a fishing assistant that stores catch records locally and uses weather/search services in ways that fit its stated purpose, though users should be aware of local storage and external weather lookups.

Install only if you are comfortable with catch details such as dates, locations, lures, and notes being saved under ~/lurefish/. For privacy, supply weather manually or ensure weather lookups use HTTPS, and treat location-based web or map searches as information sent to external services.

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

Warning
Location
scripts/log_catch.py:39
Finding
Weather Data Is Retrieved Over Unencrypted HTTP## Vulnerability Details **File Location**: `scripts/log_catch.py:39-44`; the insecure command is also documented in `SKILL.md:35` **Vulnerability Type**: Plaintext external service communication **Risk Level**: Medium **Complete Code Snippet**: ```python try: result = subprocess.run( ["curl", "-s", "wttr.in/?format=%t+%w+%p"], capture_output=True, text=True, timeout=5 ) return result.stdout.strip() if result.stdout.strip() else "Unknown" ``` The documentation similarly instructs the agent to invoke `curl` with a `wttr.in` URL that omits the HTTPS scheme. ### Technical Analysis The URL does not specify `https://`. Curl consequently initiates the request using plaintext HTTP. Even if the remote service normally redirects clients to HTTPS, the initial request remains unprotected and can be observed or modified before a secure connection is established. An attacker with a privileged network position, such as a malicious wireless access point, compromised router, or local network adversary capable of traffic interception, can read the weather request and return arbitrary output. The script accepts any nonempty standard output without checking the HTTP status, final protocol, server identity beyond curl defaults, or response structure. The returned content may then be stored as the weather field in `~/lurefish/catches.json`. The fixed subprocess argument list and absence of `shell=True` prevent this issue from becoming shell command injection. The remote response is treated as text rather than executable code. ### Attack Path 1. A user records a catch without explicitly supplying the `--weather` argument. 2. `log_catch()` calls `get_weather()`. 3. The script initiates a plaintext HTTP request to `wttr.in`. 4. A network-positioned attacker intercepts the request before any possible HTTPS redirect. 5. The attacker returns a forged weather response or redirects the request to an attacker- ...[truncated 813 chars]
Remediation
## Remediation Suggestions 1. Specify HTTPS explicitly: ```python result = subprocess.run( [ "curl", "--fail", "--silent", "--show-error", "--proto", "=https", "--max-redirs", "0", "https://wttr.in/?format=%t+%w+%p", ], capture_output=True, text=True, timeout=5, check=False, ) ``` 2. Update `SKILL.md` so every example uses `https://wttr.in/...`. 3. If a city is supplied, encode it with a URL-building library rather than interpolating raw user input into a URL. 4. Check the subprocess return code and reject unsuccessful requests instead of trusting any nonempty standard output. 5. Validate the response against the expected weather format and impose a reasonable response-size limit before storing it. 6. Avoid silently following redirects. If redirects are required, permit only HTTPS destinations on an explicit allowlist. 7. Catch specific exceptions, such as `subprocess.TimeoutExpired` and `OSError`, rather than using a bare `except` clause.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (13)

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill references shell execution (`curl`), file reads/writes, and local scripts, but does not declare any explicit tool scope or permissions. This creates an over-broad execution surface where the agent may use powerful capabilities without transparent limits, increasing the risk of unintended file modification or command execution.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger description is broad enough to match common conversation topics such as weather, locations, or general fishing-related chat. Over-triggering can cause the skill to activate in contexts where the user did not intend local storage or external lookups, which increases privacy and consent risk.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill instructs use of external services such as `wttr.in` and online search without warning that user-supplied location or query terms will be sent off-device. This can leak location, travel habits, or fishing spot interests to third parties without informed consent.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill states that it will automatically create `~/lurefish/` and persist user records there, but does not clearly warn the user beforehand or obtain consent. Silent local persistence of activity, location, and catch history can expose sensitive behavioral data on shared or unmanaged systems.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The script silently contacts an external service when weather is not supplied, without warning the user that a network request will occur. Even though it sends no obvious user-entered payload, it still leaks metadata such as the user's IP address and execution timing to a third party, which is a privacy and policy risk in a local-recording tool context.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def get_weather():
    """尝试获取当前天气"""
    try:
        result = subprocess.run(
            ["curl", "-s", "wttr.in/?format=%t+%w+%p"],
            capture_output=True, text=True, timeout=5
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This Python file contains user-facing natural-language documentation entirely in Chinese, including the title and usage examples. Under the policy rule, forcing a specific language without user opt-in or a documented regional justification is a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
L004-L009 的技能名称、描述与面向用户的说明全部固定为中文,且没有说明可根据用户偏好切换语言。按规则,若技能隐含强制特定语言而未提供用户选择,属于语言/locale 策略风险。

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
This markdown file is entirely written in Chinese and does not indicate that the skill offers alternative language options or that it is intentionally limited to a Chinese-speaking audience. Under the policy rule for language/locale constraints, a skill that implicitly forces one language without opt-in can be a natural-language policy concern.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
This markdown file presents all user-facing content in Chinese, with no indication that language selection is optional or that the skill is intentionally limited to Chinese-speaking users. Under the policy rule for language or locale constraints, a fixed language can be a violation when no opt-in or justification is provided.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
The script's docstring, prompts, help text, and output messages are all exclusively in Chinese, which imposes a single language for user interaction. There is no indication that this locale choice is optional, configurable, or justified as region-specific.

Context-Inappropriate Capability

Low
Confidence
87% confidence
Finding
模块说明和函数用途聚焦于“渔获记录”,但 get_weather() 通过 subprocess 调用 curl 访问 wttr.in 获取天气。这为本地记录脚本增加了网络访问与外部命令执行能力;虽然对整体技能“天气查询/渔获记录”并非完全无关,但对该文件声明的记录用途来说并不是直接必要能力。

Intent-Code Divergence

Low
Confidence
88% confidence
Finding
The module docstring advertises `python stats.py --top 5` as a way to control TOP N output, but when `--month` is used the code calls `stats_summary(month_catches)` without passing `args.top`, causing the default value 5 to be used instead. This is a real documentation-to-code mismatch, though limited in impact to user intent rather than security-sensitive behavior.

Static analysis

No suspicious patterns detected.