Back to skill

Security audit

Abfallkalender RV

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but its downloader trusts a server-provided filename in a way that could overwrite files outside the intended location.

Review before installing. Prefer running the script with an explicit --output path in a dedicated directory, and use --no-cache if you do not want your address and calendar retained locally. The skill should ideally sanitize server filenames and restrict cache permissions before broad use.

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
scripts/download_waste_calendar.py:337
Finding
Server-Controlled Filename Allows Arbitrary File Write## Vulnerability Details **File Location**: `scripts/download_waste_calendar.py`, lines 337–340 and 387–395 **Vulnerability Type**: Unsanitized server-provided filename and path traversal **Risk Level**: High ```python def extract_filename(headers) -> str | None: disposition = headers.get("Content-Disposition", "") match = re.search(r'filename="?([^";]+)"?', disposition) return match.group(1) if match else None ``` ```python def choose_output_path(requested_path: str | None, filename: str) -> Path: if requested_path: return Path(requested_path).expanduser().resolve() return Path.cwd() / filename def write_file(path: Path, data: bytes) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_bytes(data) ``` ### Technical Analysis The filename extracted from the HTTP `Content-Disposition` response header is passed directly into `Path.cwd() / filename`. The application does not remove path separators, reject absolute paths, normalize the resulting path, or verify that the resolved destination remains inside the current working directory. A filename containing traversal components, such as `../../target`, can therefore escape the intended output directory. Under `pathlib` semantics, an absolute filename can also cause the current working directory operand to be discarded. The subsequent `mkdir(parents=True, exist_ok=True)` creates missing parent directories, while `write_bytes()` overwrites an existing destination without confirmation. HTTPS protects the connection in transit but does not establish that a filename supplied by the remote application is safe for local filesystem use. Exploitation requires control over or compromise of the download response, such as through a compromised portal, an upstream server-side flaw, or a compromised trusted TLS endpoint. ### Attack Path 1. The user runs the Skill without supplying `--output`. 2. The Skill requests an ICS o ...[truncated 1014 chars]
Remediation
## Remediation Suggestions - Treat the server-provided filename only as a display name and reduce it to a basename using `Path(filename).name`. - Reject absolute paths, `..` components, path separators, control characters, and unexpected filename characters. - Resolve the final path and verify that it remains within an explicitly selected output directory, for example with `resolved_path.is_relative_to(resolved_output_directory)`. - Generate a local fixed filename such as `waste-calendar.ics` or `waste-calendar.pdf` when no explicit output path is supplied. - Require explicit confirmation or a dedicated overwrite option before replacing an existing file. - Prefer exclusive file creation where appropriate and handle symbolic links safely to reduce overwrite and link-following risks.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/download_waste_calendar.py:192
Finding
Address and Calendar Cache Uses Ambient Filesystem Permissions## Vulnerability Details **File Location**: `scripts/download_waste_calendar.py`, lines 192–211 **Vulnerability Type**: Plaintext sensitive metadata stored without explicit restrictive permissions **Risk Level**: Low ```python def write_cache_entry( cache_dir: Path, city: str, street: str, house_number: str, house_number_suffix: str, file_format: str, filename: str, data: bytes, ) -> CacheEntry: data_path, meta_path = cache_paths( cache_dir, city=city, street=street, house_number=house_number, house_number_suffix=house_number_suffix, file_format=file_format, ) cache_dir.mkdir(parents=True, exist_ok=True) data_path.write_bytes(data) metadata = { "city": city, "street": street, "house_number": house_number, "house_number_suffix": house_number_suffix, "format": file_format, "filename": filename, "downloaded_at_epoch": int(time.time()), } meta_path.write_text(json.dumps(metadata, indent=2, ensure_ascii=True) + "\n", encoding="utf-8") return CacheEntry(data_path=data_path, meta_path=meta_path, metadata=metadata) ``` ### Technical Analysis The cache stores the requested city, street, house number, house-number suffix, original filename, timestamp, and downloaded calendar in plaintext. The directory and files are created without explicit permission modes, so their effective accessibility depends on the process umask and any permissions inherited from an existing user-selected cache directory. On a conventional system with a secure umask, the exposure may be limited. On a shared system with a permissive umask or an inadequately protected custom `--cache-dir`, other local users may be able to inspect precise address information and calendar contents. ### Attack Path 1. A user invokes the Skill with caching enabled, whic ...[truncated 791 chars]
Remediation
## Remediation Suggestions - Create the cache directory with mode `0700` and verify or correct the permissions of an existing directory before use. - Create cache data and metadata files with mode `0600`, preferably through low-level exclusive creation followed by atomic replacement. - Reject or warn about a cache directory that is writable or readable by unintended users. - Document that the cache retains precise address information and calendar contents. - Provide a supported cache-clearing operation and retain the existing `--no-cache` option for users who do not want persistent storage. - Consider minimizing metadata by avoiding redundant plaintext address fields where they are not necessary for cache validation.
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 (2)

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill invokes a local Python script that performs network access and reads/writes files, but the manifest does not declare any tool scope or allowed tools. This creates a permission-transparency gap: a caller or platform cannot easily enforce least privilege, and the skill may receive broader capabilities than its documented purpose requires.

Missing User Warnings

Low
Confidence
77% confidence
Finding
This markdown file explains that the skill downloads the waste calendar and shows running the script directly, but it does not explicitly warn users that executing the skill performs network retrieval from an external source. For markdown files, the guidance asks for warnings when behavior could affect privacy or system integrity; here the omission is minor but present because the skill's behavior involves external data access.

Static analysis

No suspicious patterns detected.