T09 · Insecure Skill Coding Practices
- 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
Security audit
Security checks for vulnerabilities and agentic risk
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.
scripts/run_with_confirmation.py:148Confirmation-Based Irrigation Bypasses the Master Automation Switch and Session Duration Limit
src/garden_irrigation/integrations/tuya.py:72Valve Can Remain Open Indefinitely When Countdown Support Is Unavailable or Misconfigured
src/garden_irrigation/engine/decision.py:25Configured Daily and Minimum-Interval Irrigation Limits Are Not Enforced
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.
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.
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.
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.
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.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
# .env (project root)
TUYA_ACCESS_ID=your_access_id
TUYA_ACCESS_SECRET=your_access_secret
TUYA_API_ENDPOINT=https://openapi.tuyaeu.com
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
"""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)
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.
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.
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.
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.
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.
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.
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.
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.
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.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
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()
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.
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.
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.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
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'
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.
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.
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.
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.
No suspicious patterns detected.