Back to skill

Security audit

Garden Irrigation

Security checks for vulnerabilities and agentic risk

Overview

This irrigation skill is mostly coherent, but it can control real water valves automatically and has under-enforced safety boundaries that users should review before installing.

Review this before installing on any real irrigation hardware. Use report-only mode unless you are comfortable with automatic valve control, verify every valve supports a reliable countdown or independent shutoff, disable notification sending unless needed, and avoid relying on the configured daily/minimum-interval safety limits until the actuation paths enforce them consistently.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run_with_confirmation.py:148
Finding

Confirmation-Based Irrigation Bypasses the Master Automation Switch and Session Duration Limit

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/garden_irrigation/integrations/tuya.py:72
Finding

Valve Can Remain Open Indefinitely When Countdown Support Is Unavailable or Misconfigured

Content
View full analysis
0: commands.append({"code": countdown_code, "value": int(minutes)}) return self.control(valve['device_id'], commands) ``` ### Technical Analysis The `open_valve_for_minutes()` method always prepares a command that switches the valve on. A device-side countdown is added only when all of the following are true: - `supports_countdown` is enabled; - `countdown_code` is configured; - `minutes` is greater than zero. If countdown support is absent or incorrectly configured, the function still opens the valve. It does not reject the operation, schedule a local close command, or otherwise guarantee that `close_valve()` will be called. The method name and caller behavior imply time-bounded operation, but the implementation does not guarantee that property. This is a fail-open design at the physical-actuation boundary. A configuration error or device capability mismatch can convert a limited irrigation request into an indefinite switch-on command. ### Attack Path 1. Configure a valve with `supports_countdown` set to `false`, omit `countdown_code`, or use a device whose countdown capability does not work as expected. 2. Trigger an irrigation decision through either actuation-capable runner. 3. The caller invokes `open_valve_for_minutes()` with a positive duration. 4. The method sends only: ```json [{"code": "switch_1", "value": true}] ``` 5. No local timer or guaranteed follow-up close command is created. 6. The valve remains open until another actor or system explicitly closes it. ### Impact Assessment The affected privilege is control of the configured Tuya valve. The valve may remain open beyond every calculated and configured durati ...[truncated 293 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/garden_irrigation/engine/decision.py:25
Finding

Configured Daily and Minimum-Interval Irrigation Limits Are Not Enforced

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (36)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill states that it reads configuration from a parent ../config directory and writes to ../data, which extends its filesystem reach beyond the local skill folder and is not reflected in the short description. Parent-directory reads and writes increase the blast radius of misconfiguration, data leakage, or interference with other nearby project files.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill states that it reads configuration from a parent ../config directory and writes to ../data, which extends its filesystem reach beyond the local skill folder and is not reflected in the short description. Parent-directory reads and writes increase the blast radius of misconfiguration, data leakage, or interference with other nearby project files.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill states that it reads configuration from a parent ../config directory and writes to ../data, which extends its filesystem reach beyond the local skill folder and is not reflected in the short description. Parent-directory reads and writes increase the blast radius of misconfiguration, data leakage, or interference with other nearby project files.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The skill states that it reads configuration from a parent ../config directory and writes to ../data, which extends its filesystem reach beyond the local skill folder and is not reflected in the short description. Parent-directory reads and writes increase the blast radius of misconfiguration, data leakage, or interference with other nearby project files.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill states that it reads configuration from a parent ../config directory and writes to ../data, which extends its filesystem reach beyond the local skill folder and is not reflected in the short description. Parent-directory reads and writes increase the blast radius of misconfiguration, data leakage, or interference with other nearby project files.

Content

No source excerpt is available for this finding.

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 · SKILL.md (reported line 116)May include surrounding context.

Setup

bash
# .env (project root)
TUYA_ACCESS_ID=your_access_id
TUYA_ACCESS_SECRET=your_access_secret
TUYA_API_ENDPOINT=https://openapi.tuyaeu.com

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · src/garden_irrigation/integrations/notifications.py (reported line 17)May include surrounding context.

python
"""Send a report to the specified bot via the OpenClaw message system.

    In an OpenClaw agent environment, we attempt to call the message tool directly.
    If that is not possible, we output instructions for external handling.

    Args:
        report_content: Report content (Markdown format)

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill metadata and README disagree on a core control input: whether watering decisions are based on the last 50 readings or a 24-hour average with fallback to current values. For a physical automation skill, this kind of documentation drift can cause operators or reviewers to misunderstand when irrigation will trigger, increasing the risk of overwatering or watering at the wrong time.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The README advertises automatic valve actuation but does not prominently warn that the skill can trigger real-world watering without direct user intervention. In a home automation context, unclear disclosure around physical actuation is dangerous because users may run the skill expecting a report and instead cause water usage, flooding, plant damage, or equipment wear.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill declares broad operational behavior without any explicit tool scoping despite clearly requiring environment access, file I/O, network access, and shell execution. In an automation skill that can actuate valves and send messages, lack of declared restrictions increases the chance of unintended capability use or privilege expansion beyond what users expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This manifest enables automatic operation and sets require_confirmation to false, which means the system may perform real-world actions without an approval step. In this file there is no accompanying warning or disclosure to the user about that behavior, which fits the missing user warnings criterion for manifest/markdown-described behavior affecting system integrity.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script does more than analyze irrigation needs: it automatically actuates physical valves via tuya.open_valve_for_minutes(...) when conditions are met. In an agent skill context, undisclosed physical actuation is security-relevant because it can trigger real-world actions without an explicit user approval boundary, increasing risk of property damage, water waste, or unsafe operation if configuration, sensor data, or logic are wrong or manipulated.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script introduces an outbound messaging channel that is not disclosed in the skill metadata and can exfiltrate operational data to an external recipient. Even though the current payload is an irrigation report, the helper can send arbitrary content to arbitrary targets from the agent environment, expanding the skill's effective permissions beyond its stated purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This block conditionally sends full generated reports to a bot based on configuration, creating outbound data flow not clearly justified by the irrigation decision function described for the skill. Because the report may include sensor/device details and environment data, this can leak internal information and normalizes cross-channel communication from a skill that users would not expect to message external accounts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The fallback path prints the bot destination, account identifier, and a preview of the report body to stdout when direct delivery is unavailable. In agent or hosted environments, stdout is often collected into centralized logs, which can expose operational details and potentially sensitive report contents to unintended readers.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code executes a Python interpreter taken from TUYA_CLOUD_PYTHON or from a workspace-controlled virtualenv, then runs a script from a sibling skill directory. If an attacker can influence environment variables or workspace contents, they can redirect execution to arbitrary code, which is especially dangerous here because the skill can perform real-world device control.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · src/garden_irrigation/integrations/tuya.py (reported line 43)May include surrounding context.

python
if not self.script.exists():
            raise FileNotFoundError(f'tuya_controller.py not found at {self.script}')
        cmd = [self.python, str(self.script), *args]
        result = subprocess.run(cmd, cwd=self.skill_dir, capture_output=True, text=True)
        if result.returncode != 0:
            stderr = (result.stderr or '').strip()
            stdout = (result.stdout or '').strip()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill executes an external Python script via subprocess, which can trigger downstream networked device operations, but there is no confirmation prompt, print/log disclosure, or comment/docstring warning users about this action. Because this file also exposes control paths that can change valve state, users may not receive clear notice that real-world device actions are being initiated.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes a smart irrigation skill that reads soil sensors, checks weather, and decides when and how long to water each zone. This file exposes a generic control(device_id, commands) interface and valve helpers that can send arbitrary Tuya command payloads to any provided device, which is broader than a narrowly scoped irrigation decision/reporting function.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The control, open_valve_for_minutes, and close_valve methods can turn irrigation valves on or off, which is a safety-relevant and potentially irreversible physical operation for the duration requested. This file contains no confirmation mechanism, user-facing notice, or warning text describing that device state will be changed.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/garden_irrigation/integrations/weather.py (reported line 11)May include surrounding context.

python
def history_and_forecast(self, latitude: float, longitude: float, timezone: str) -> dict:
        """Fetch rolling 7-day history + 3-day forecast from Open-Meteo in a single call."""
        url = (
            'https://api.open-meteo.com/v1/forecast'
            f'?latitude={latitude}&longitude={longitude}'
            '&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,weathercode'
            f'&timezone={timezone}&past_days=7&forecast_days=3'

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The configuration helper copies every file from a parent ../config directory into the skill-local config directory and overwrites existing files without validation or scoping. That gives this irrigation skill write effects outside its stated sensor/weather decision role and allows external parent-directory content to silently alter zone or system behavior, making the skill's operation dependent on untrusted filesystem state.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The parent-directory sync behavior is real and not justified by the manifest description of an irrigation decision tool. Because it imports and overwrites local configuration from outside the skill boundary, an attacker or another component with access to ../config can influence watering rules or inject unexpected files, creating a trust-boundary violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code overwrites local configuration files automatically during object initialization, with no warning, confirmation, backup, or audit trail. In the irrigation context, silent config replacement can change watering schedules or zone definitions unexpectedly, potentially causing property damage, water waste, or operational disruption.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code explicitly falls back to English when language is 'auto' or unsupported, which forces a locale choice rather than preserving user choice. This also occurs in the broader config flow, making English the default output even when the user's language preference is unknown.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.