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.
