T09 · Insecure Skill Coding Practices
- Location
SKILL.md:12- Finding
User-Controlled Location Can Be Interpolated into Shell Commands
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This weather skill is mostly purpose-aligned, but its shell-command examples interpolate user locations unsafely and could allow command injection.
Install only if you trust the unofficial api.openmeteo-api.com wrapper with location queries, and avoid using this skill with untrusted or adversarial location text unless the commands are rewritten to pass the location as encoded data rather than substituted into shell source.
SKILL.md:12User-Controlled Location Can Be Interpolated into Shell Commands
SKILL.md:51Weather Queries Are Forced Through an Unofficial and Unaudited Intermediary
The manifest description says to use this skill when the user asks about weather, temperature, forecasts, air quality, UV index, or weather alerts for any location. While weather-related, this activation guidance is still broad and provides no exclusion conditions or negative examples, which could cause the skill to be invoked for loosely related everyday questions involving temperature or air quality context.
This skill sends user-supplied location data to a third-party wrapper domain rather than directly to the official upstream weather provider. That creates an unnecessary external transmission and trust expansion: the wrapper can observe user queries and request metadata, and the skill explicitly instructs agents to prefer it over direct upstream calls.
curl -s "https://api.openmeteo-api.com/api/current?location=CITY"
This forecast endpoint transmits the user's requested location to a non-official proxy service. Even if the data is not highly sensitive in many cases, location queries can reveal travel, home, work, or intent patterns, and the wrapper adds an avoidable intermediary.
curl -s "https://api.openmeteo-api.com/api/forecast?location=CITY&days=5"
The air-quality request sends the user's location to an external wrapper service, exposing potentially sensitive location interest data to an additional operator. The skill's own text confirms that requests are forwarded to upstream APIs, so the wrapper sees all traffic in transit.
curl -s "https://api.openmeteo-api.com/api/air-quality?location=CITY"
This UV endpoint has the same trust-boundary issue: user location is transmitted to a third-party convenience domain not affiliated with the official weather source. The context makes this moderately dangerous because weather requests commonly include real locations, which are privacy-relevant even if not credentials or secrets.
curl -s "https://api.openmeteo-api.com/api/uv?location=CITY"
Severe weather alert queries can reveal a user's current or planned location and are sent through an unaffiliated proxy service. Because alerts may be checked during emergencies or travel, the contextual sensitivity of the transmitted location can be higher than routine informational requests.
curl -s "https://api.openmeteo-api.com/api/alerts?location=CITY"
The quick one-liner endpoint still sends location data to the same unaffiliated external service, so convenience does not reduce the underlying privacy and trust risk. The issue is the extra operator and mandatory routing through it, not the endpoint shape.
curl -s "https://api.openmeteo-api.com/api/quick?location=CITY"
This section explicitly describes a Cloudflare Worker proxy that forwards requests to upstream APIs in real time, confirming that user queries traverse an additional third party. Security claims like 'no persistent storage' and 'stateless' are unverifiable within the skill and do not remove the privacy risk from external transmission and possible infrastructure logging.
- **Upstream sources**: All weather data originates from [open-meteo.com](https://open-meteo.com) (free, open-source) and [wttr.in](https://wttr.in). This wrapper does not generate any weather data itself.
- **Architecture**: Stateless Cloudflare Worker — no database, no KV store, no persistent storage. Requests are proxied to upstream APIs in real time.
- **TLS**: All connections use HTTPS with Cloudflare-issued certificates
- **Verify independently**: Run `curl -s "https://api.openmeteo-api.com/api/current?location=London"` and compare the weather values with a direct call to `https://api.open-meteo.com/v1/forecast?latitude=51.51&longitude=-0.13¤t=temperature_2m` — they will match because the data comes from the same upstream source.
## Verify It Yourself
This section explicitly describes a Cloudflare Worker proxy that forwards requests to upstream APIs in real time, confirming that user queries traverse an additional third party. Security claims like 'no persistent storage' and 'stateless' are unverifiable within the skill and do not remove the privacy risk from external transmission and possible infrastructure logging.
- **Upstream sources**: All weather data originates from [open-meteo.com](https://open-meteo.com) (free, open-source) and [wttr.in](https://wttr.in). This wrapper does not generate any weather data itself.
- **Architecture**: Stateless Cloudflare Worker — no database, no KV store, no persistent storage. Requests are proxied to upstream APIs in real time.
- **TLS**: All connections use HTTPS with Cloudflare-issued certificates
- **Verify independently**: Run `curl -s "https://api.openmeteo-api.com/api/current?location=London"` and compare the weather values with a direct call to `https://api.open-meteo.com/v1/forecast?latitude=51.51&longitude=-0.13¤t=temperature_2m` — they will match because the data comes from the same upstream source.
## Verify It Yourself
The verification example normalizes direct use of the third-party wrapper and encourages installation despite the additional trust boundary. This makes the context more dangerous because the skill repeatedly steers usage toward the unaffiliated proxy rather than minimizing third-party exposure.
You can test the API directly before installing:
curl -s "https://api.openmeteo-api.com/api/current?location=London"
Expected response (JSON):
No suspicious patterns detected.