Back to skill

Security audit

Travel Morning Weather

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says at a high level, but it stores sensitive travel data automatically and documents unsafe shell-style commands using conversation-derived locations.

Review this skill before installing. It is not clearly malicious, but only use it if you are comfortable with an agent storing your home city and travel schedule, automatically updating that file from chat, and running the documented commands. Prefer a revised version that requires confirmation before saving trips, validates locations, URL-encodes weather requests, and invokes scripts/curl with structured arguments rather than shell-interpolated strings.

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

Error
Location
SKILL.md:36
Finding
Command Injection Through Conversation-Derived Travel Location<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 36-39 **Vulnerability Type**: Shell command injection **Risk Level**: High ### Vulnerable Code ```bash python3 skills/travel-morning-weather/scripts/update-travel-plan.py \ --start YYYY-MM-DD --end YYYY-MM-DD --location "City, Country" ``` The same unsafe command-construction pattern is also demonstrated in `references/capture-triggers.md`, lines 27-29. ### Technical Analysis The skill instructs the agent to extract a location from conversation content and interpolate it into a shell command. The location is therefore untrusted input under the control of the user or another party whose content is processed by the agent. Wrapping the interpolated value in double quotes is not sufficient shell protection. Shell command substitution remains active inside double quotes, and an embedded double quote can terminate the intended argument. If the generated command is executed through a shell, payloads containing constructs such as `$(...)`, backticks, or a quote followed by shell metacharacters may execute unintended commands. The Python script itself uses `argparse` and does not invoke a shell. The vulnerability arises in the documented agent-to-script invocation method, where conversational data may be incorporated into shell syntax before Python receives the arguments. ### Attack Path 1. An attacker supplies or causes the agent to process a travel statement containing a malicious location, for example a value containing shell command substitution. 2. The skill proactively extracts that value as the location, as directed by its travel-capture instructions. 3. The agent substitutes the untrusted value into the documented `--location "..."` shell command. 4. The command is executed through a shell. 5. The shell evaluates the injected syntax before launching the Python script. 6. The injected command runs with the same operating-system identity and permissions as the agent process. Succes ...[truncated 840 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not construct a shell command by interpolating conversation-derived values. 2. Invoke the script with a structured argument array and disable shell processing. For example, the hosting implementation should use an equivalent of: ```python subprocess.run( [ "python3", "skills/travel-morning-weather/scripts/update-travel-plan.py", "--start", start_date, "--end", end_date, "--location", location, ], shell=False, check=True, ) ``` 3. Validate dates strictly with `datetime.strptime()` before invocation. 4. Validate location length and reject control characters such as NUL, carriage return, and newline. 5. If a shell is unavoidable, apply platform-appropriate argument escaping to every dynamic value. Validation alone should not replace safe argument-array execution. 6. Update `SKILL.md`, `references/capture-triggers.md`, and `references/data-format.md` to explicitly prohibit shell interpolation of conversation-derived data. 7. Add tests using locations containing quotes, command substitutions, semicolons, newlines, and leading hyphens to verify that they are passed only as literal argument data. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
references/morning-briefing.md:20
Finding
Delayed Command Injection Through the Weather Query<![CDATA[ ## Vulnerability Details **File Location**: `references/morning-briefing.md`, line 20 **Vulnerability Type**: Shell command injection through persisted location data **Risk Level**: High ### Vulnerable Code ```bash curl -s "wttr.in/<City,Country>?format=%l:+%c+%t+(feels+like+%f)" ``` ### Technical Analysis The documented morning briefing retrieves a location from `travel-plan.json` and places it into a quoted curl command. Travel locations can originate from conversation content and are persisted in `daily_locations`. Consequently, the command may combine shell syntax with attacker-controlled stored data. Double quotes do not prevent shell command substitution. A malicious location containing `$(...)` or backticks can be evaluated by the shell even if it remains inside the surrounding quotes. A value containing an injected double quote may also terminate the URL argument and introduce additional shell syntax. This creates a stored or delayed command-injection condition: the malicious value can be written during one conversation and executed later when the scheduled morning briefing runs. The Python storage script writes the location as JSON data without executing it, but no validation prevents dangerous shell characters from reaching the later curl command. ### Attack Path 1. An attacker provides a travel location containing shell syntax. 2. The agent captures the location and saves it in `memory/travel-plan.json`. 3. The malicious entry remains stored until its corresponding date. 4. The morning briefing reads the location for the current date. 5. The implementation substitutes the stored value into the documented curl command. 6. When the command is executed through a shell, the shell evaluates the injected syntax. 7. The payload executes under the identity used by the scheduled morning briefing. This path requires the briefing implementation to interpolate the location into the shell command as documented. The referenced `scripts/morning-b ...[truncated 848 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Avoid shell-based URL construction. Prefer a maintained HTTP client library that accepts query parameters as structured data. 2. If curl must be used, invoke it with an argument array and `shell=False`, ensuring the complete URL is passed as one literal argument. 3. URL-encode the location using a standard URL-encoding function rather than directly concatenating it into the URL. 4. Use an explicit HTTPS endpoint: ```text https://wttr.in/ ``` 5. Validate stored locations before use. Enforce a reasonable maximum length and reject control characters. Consider resolving locations to a trusted canonical city identifier before persistence. 6. Treat `travel-plan.json` as untrusted data even though it is local, because its values originate from conversations. 7. Add regression tests with locations containing `$()`, backticks, quotes, semicolons, ampersands, whitespace, and newline characters. 8. Provide the missing briefing implementation and ensure it documents structured process execution rather than shell interpolation. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared purpose suggests a simple weather-location adjustment, but the skill also performs persistent data mutation, cleanup/deletion of stored entries, and cron/CLI-style maintenance behavior. This mismatch can mislead users and reviewers about the real capabilities of the skill, causing them to approve or invoke behavior that alters stored personal data beyond the advertised function.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README explicitly promotes automatic capture of travel plans from conversation and persistent storage, but it does not warn users that potentially sensitive itinerary/location data will be extracted and retained. Travel history and future presence information are privacy-sensitive; silent collection increases the risk of unintended disclosure, over-collection, or user surprise in environments where conversation logs may contain personal schedules.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The installation and setup instructions tell users to create `memory/travel-plan.json`, but the README does not clearly disclose that the skill will later write to and automatically modify this file, including cleanup of past entries. Undocumented autonomous modification of persistent memory can affect user trust, create integrity issues for shared agent state, and expose sensitive travel data if users assume the file is static or manually managed.

Lp3

Medium
Category
MCP Least Privilege
Confidence
83% confidence
Finding
The skill reads and writes persistent memory data but does not declare an explicit tool scope or permissions boundary. That creates an authorization transparency gap: reviewers and users cannot easily tell that the skill can modify local state, which increases the risk of unintended persistence or misuse if the surrounding agent grants broad file capabilities.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill instructs the agent to create a persistent travel-plan file containing home city and future locations derived from conversation, but it does not require clear user notice or consent for storing this personal travel data. Travel history and home location are sensitive contextual data and can expose routine, whereabouts, or household absence if retained without informed consent.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
Hard-coding Asia/Shanghai for invocation and date resolution can cause the skill to use the wrong day or briefing time for users in other regions, which may incorrectly select or expire travel locations. While not a direct security exploit by itself, it can lead to privacy-affecting mistakes or integrity issues in user-specific data handling.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The instruction to update travel data proactively whenever the user mentions travel plans causes automatic persistence of conversation-derived personal information without a warning at the point of capture. This is especially risky because users may mention tentative or sensitive travel in ordinary conversation without expecting it to be stored and later acted upon.

Natural-Language Policy Violations

Medium
Confidence
87% confidence
Finding
The file presents its title, triggers, workflow, and example responses exclusively in Chinese, including the mandated assistant reply. This can constitute a language-policy issue if the skill forces a specific language without giving the user an opt-in choice or stating that the skill is intentionally limited to a Chinese-speaking context.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The document instructs the agent to proactively capture travel details from conversation and automatically write them into `travel-plan.json` without any explicit consent gate, retention notice, or warning that stored user data will be modified. Because travel plans are sensitive location and schedule data, silent persistence increases privacy risk and can lead to unauthorized profile building or incorrect downstream behavior if the extraction is wrong.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
This markdown file presents key operational guidance, field descriptions, update commands, and safety rules entirely in Chinese, while the title is in English. That creates a language policy concern because the skill documentation effectively forces a specific language without any user opt-in or stated region-specific justification.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The module docstring, CLI help text, comments, and printed status/error messages are all written in Chinese, which imposes a specific language on users. The file does not offer any locale selection or indicate that the tool is intentionally region-specific, so this is a natural-language policy concern.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The JSON file specifies destination cities exclusively in France for multiple dates, which can reflect a fixed locale-specific configuration without any indication that the user opted into that locale or that the restriction is justified. Under the policy rule for natural-language locale constraints, hard-coded location assumptions can be problematic when no choice or rationale is provided.

Natural-Language Policy Violations

Low
Confidence
94% confidence
Finding
The module docstring and all user-facing usage text are written only in Chinese, and the script also hard-codes a UTC+8 timezone assumption. This imposes a specific language/locale context without offering any user choice or documenting that the skill is intentionally region-specific.

Static analysis

No suspicious patterns detected.