Back to skill

Security audit

Photo Webcam

Security checks for vulnerabilities and agentic risk

Overview

This webcam snapshot skill has a coherent purpose, but its script can fetch unrestricted URLs and write to arbitrary paths before images may be sent through Telegram.

Review this skill before installing. It is not clearly malicious, but only use it where unrestricted outbound network requests and local file writes are acceptable. Keep favorites limited to trusted webcam URLs, verify any Telegram destination, and avoid running it with elevated privileges or against untrusted favorite files.

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/foto_webcam_snapshot.py:38
Finding

Server-Side Request Forgery Through Unrestricted Webcam URLs

Content
View full analysis
str: r = requests.get(page_url, headers={"User-Agent": UA, "Accept": "text/html"}, timeout=30) r.raise_for_status() html = r.text ``` ```python def download_image(url: str) -> bytes: r = requests.get(url, headers={"User-Agent": UA, "Accept": "image/avif,image/webp,image/apng,image/*,*/*"}, timeout=30) r.raise_for_status() return r.content ``` ```python page_url = a.url fav_name = None fav_id = a.id source_url = None if a.favorites and a.id is not None: fav = read_favorites(a.favorites) items = fav.get("items") or [] hit = next((it for it in items if int(it.get("id")) == int(a.id)), None) if not hit: raise RuntimeError(f"Favorite id not found: {a.id}") fav_name = hit.get("name") page_url = hit.get("page") source_url = hit.get("image") if not page_url: raise RuntimeError("Missing --url or --favorites+--id") if not source_url: source_url = resolve_current_image_from_page(page_url) ``` ### Technical Analysis The script passes URLs from the `--url` argument and from the `page` or `image` properties of a favorites file directly to `requests.get()`. It does not validate the URL scheme, destination hostname, resolved IP address, port, or redirect targets. Consequently, a caller able to control the URL or favorites data can make the process issue requests to loopback addresses, private network ranges, link-local services, or cloud instance metadata endpoints. The `requests` library follows redirects by default, so checking only an initial hostname would not be sufficient. In addition, the g ...[truncated 1339 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/foto_webcam_snapshot.py:68
Finding

Arbitrary File Overwrite Through Unrestricted and Predictable Output Paths

Content
View full analysis
--message “Webcam N Name” --media /tmp/webcamN.jpg ``` ### Technical Analysis The caller can select any output path through `--out`. The path is not constrained to an approved directory, canonicalized, or checked for symbolic links. Opening it with mode `"wb"` follows symbolic links and truncates an existing target before writing. The documented `/tmp/webcamN.jpg` naming convention is predictable. On a shared system, another local process can create a symbolic link at that path before the skill runs. When the skill opens the path, the downloaded response is written to the symlink target. There is also a time-of-check/time-of-use concern if a separate validation step were added without atomic file creation. ### Attack Path 1. An attacker predicts that the skill will use a path such as `/tmp/webcam1.jpg`. 2. Before execution, the attacker creates that path as a symbolic link to another file writable by the skill process. 3. The skill downloads attacker-controlled or ordinary remote content. 4. `open(a.out, "wb")` follows the symbolic link and truncates the target. 5. The downloaded bytes ...[truncated 671 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/foto_webcam_snapshot.py:58
Finding

Unbounded and Unvalidated Remote Content Download

Content
View full analysis
bytes: r = requests.get(url, headers={"User-Agent": UA, "Accept": "image/avif,image/webp,image/apng,image/*,*/*"}, timeout=30) r.raise_for_status() return r.content ``` ```python data = download_image(source_url) os.makedirs(os.path.dirname(a.out) or ".", exist_ok=True) with open(a.out, "wb") as f: f.write(data) ``` ### Technical Analysis Accessing `r.content` buffers the entire response in process memory before writing it to disk. The 30-second request timeout does not impose a response-size limit and does not guarantee a strict total transfer deadline. The script also does not validate `Content-Length`, MIME type, file signature, image format, dimensions, or decoded image integrity. A malicious or compromised endpoint can therefore return a very large response or arbitrary non-image bytes. The response can consume substantial memory and disk space, and arbitrary content may be stored with a `.jpg` extension and passed into the documented messaging workflow. ### Attack Path 1. An attacker controls a configured image URL, page URL, redirect destination, or a URL discovered by the generic HTML fallback. 2. The endpoint returns an oversized response or arbitrary non-image data. 3. `requests` buffers the complete body through `r.content`, causing memory consumption proportional to the response size. 4. The complete response is written to disk without a maximum size or image check. 5. The resulting file may consume available storage or be forwarded as media to another component that assumes it is a valid image. ### Impact Assessment A successful attack can exhaust process memory, consume disk space, terminate the skill, or affect oth ...[truncated 321 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

The skill description and the detected behavior are inconsistent: it claims favorites management and chat delivery, while the underlying behavior appears to save files locally and emit JSON rather than performing the declared user-facing actions. This mismatch is dangerous because reviewers and users may authorize the skill based on an incomplete understanding, while hidden filesystem writes or unimplemented messaging paths can create unsafe assumptions and bypass scrutiny.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill describes reading a workspace file and fetching remote webcam content, but it declares no explicit tool scope or permissions boundaries. In an agent environment, missing scope declarations can cause the skill to run with broader-than-expected file and network capabilities, making review, enforcement, and user consent weaker.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill instructs sending retrieved images to a Telegram target via an external CLI without any explicit user warning, confirmation, or disclosure that data will leave the local environment. Even if the content is 'just a webcam image,' silent exfiltration to third-party messaging infrastructure is a meaningful security and privacy risk in agent workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The maintenance instructions tell the agent to append entries to a workspace favorites file, but they do not warn that persistent workspace data will be modified. Undisclosed state changes can surprise users, enable unintended persistence, and create a path for poisoning future executions by inserting malicious or untrusted URLs into the favorites list.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.