Back to skill

Security audit

Tübingen Weather Graphics

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but its optional setup creates a persistent daily agent task that sends content through Telegram without enough scoping or removal guidance.

Install only if you are comfortable with a daily recurring OpenClaw task sending weather output through Telegram. If you use the automatic setup, keep the script and virtual environment in a private durable location, pin dependencies, and make sure you know how to list and remove the cron entry.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T06 · System Persistence

Warning
Location
SKILL.md:29
Finding
Persistent Scheduled Agent Execution Through OpenClaw Cron<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 29-45 **Vulnerability Type**: Persistent scheduled task **Risk Level**: Medium ### Complete Code Snippet ```bash ## Automatischer Versand 1. **Cron-Job 07:30 (Beispiel):** ```bash openclaw cron add <<'JSON' { "name": "tuebingen-forecast-graphic", "schedule": { "kind": "cron", "expr": "30 7 * * *", "tz": "Europe/Berlin" }, "sessionTarget": "isolated", "payload": { "kind": "agentTurn", "model": "default", "message": "Run `/tmp/tuebingen-plot/bin/python skills/tuebingen-weather-graphics/scripts/generate_forecast_graph.py --output data/weather/tuebingen_forecast.png`. Send Master the summary text plus attach the PNG." } } JSON ``` 2. **Telegram Versand:** `message.send` mit `media=data/weather/tuebingen_forecast.png`. ``` ### Technical Analysis The documented setup registers a daily OpenClaw cron entry that persists after the initial Skill execution. At 07:30 each day, the entry starts an isolated Agent turn, directs it to execute a script from a mutable local path, and requests transmission of the generated output through Telegram. Although weather delivery is the stated purpose and installation requires the user to run the command, the scheduled task creates a durable execution mechanism. The task does not pin or verify the identity or integrity of the script before each execution. If an attacker or another process later gains write access to the referenced script or its Python environment, the persistent scheduler could repeatedly execute altered code under the scheduler's permissions. The configuration also does not document how to inspect, disable, or remove the task, increasing the possibility that users will retain unattended execution longer than intended. ### Attack Path 1. A user follows the automatic-delivery instructions and runs `openclaw cron add`. 2. OpenClaw creates the persistent `tuebingen-forecast-graphic` ...[truncated 1237 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make scheduled execution explicitly opt-in and display a clear warning that the task persists across sessions. 2. Document commands for listing, disabling, and permanently removing the cron entry. 3. Reference a canonical absolute script path rather than a mutable relative project path. 4. Store the script and virtual environment in a location writable only by the owning administrative account; avoid long-lived executable environments under `/tmp`. 5. Before each execution, verify the script and dependency environment against an approved cryptographic hash or signed release. 6. Prefer a narrowly scoped non-Agent scheduler when the operation only needs to fetch fixed weather data and generate an image. 7. Restrict the scheduled process to the minimum filesystem, network, and messaging permissions required. 8. Require explicit confirmation before enabling Telegram delivery, and constrain delivery to an approved recipient. ]]>

T08 · Insecure Dependencies

Note
Location
SKILL.md:13
Finding
Unpinned Third-Party Dependency Installation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 13-18 **Vulnerability Type**: Unpinned dependency and transitive supply-chain exposure **Risk Level**: Low ### Complete Code Snippet ```bash - `matplotlib`, `numpy`, `pillow` (am einfachsten via virtuelles Environment): ```bash python3 -m venv /tmp/tuebingen-plot source /tmp/tuebingen-plot/bin/activate pip install matplotlib ``` ``` ### Technical Analysis The installation command retrieves `matplotlib` and its transitive dependencies without specifying reviewed versions or cryptographic hashes. Package resolution therefore depends on the packages and versions available from pip's configured index at installation time. This makes installation non-reproducible and exposes users to upstream package compromise, compromised transitive dependencies, unexpected future releases, or use of an untrusted package index configured in the local pip environment. Python packages may execute build-backend or installation-related code during installation, while installed packages execute code when imported by the forecast script. The documented virtual environment limits package contamination of the global Python installation but does not prevent malicious package code from running with the installing user's privileges. No evidence was found that the project intentionally names a malicious or typosquatted package; the risk arises from mutable, unverified dependency resolution. ### Attack Path 1. A user creates and activates the documented virtual environment. 2. The user runs `pip install matplotlib`. 3. pip contacts its configured package index and resolves the latest compatible `matplotlib` release and transitive dependencies. 4. An upstream release, transitive dependency, package-index response, or locally configured index is compromised or supplies malicious content. 5. Malicious package code executes during build, installation, or later import. 6. The code receives the privileges of the ...[truncated 623 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Provide a reviewed lock file or requirements file containing exact versions for all direct and transitive dependencies. 2. Record cryptographic hashes and install with hash enforcement, for example: ```bash python -m pip install --require-hashes -r requirements.txt ``` 3. Pin the expected package index to a trusted HTTPS repository and prevent fallback to unapproved extra indexes. 4. Periodically update dependencies through a controlled review process that includes vulnerability and provenance checks. 5. Prefer binary wheels from trusted sources where appropriate, and avoid unnecessary source builds. 6. Store the virtual environment in a private, durable application directory rather than `/tmp`, with permissions that prevent modification by other users. 7. Run installation and forecast generation as a dedicated least-privileged account without access to unrelated sensitive files or credentials. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill invokes a script that fetches data from Open-Meteo, so it has network capability, but the manifest does not declare any explicit tool scope or permissions. That creates a transparency and governance gap: an agent or reviewer cannot easily tell from the skill metadata that outbound network access is required, which can lead to overbroad execution in environments that rely on manifest-declared capabilities.

External Transmission

Medium
Category
Data Exfiltration
Content
import matplotlib.pyplot as plt  # type: ignore

API_URL = (
    "https://api.open-meteo.com/v1/forecast?latitude=48.5216&longitude=9.0576"
    "&daily=temperature_2m_max,temperature_2m_min,precipitation_probability_max"
    "&timezone=Europe/Berlin"
)
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Low
Confidence
88% confidence
Finding
The documentation instructs automatic Telegram sending of the generated summary and PNG without an explicit warning that content will be transmitted to an external service. Even if the payload is only weather data, silent or poorly disclosed outbound transmission reduces user awareness and can normalize exfiltration patterns in agent skills.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The file contains multiple hard-coded German user-facing strings, including the module description, chart labels, CLI description, and printed summary. This enforces a specific language/locale without user opt-in, which matches the natural-language policy violation category for locale constraints.

Static analysis

No suspicious patterns detected.