Back to skill

Security audit

Webcam Motion Monitor

Security checks for vulnerabilities and agentic risk

Overview

The skill is a real webcam-monitoring package, but it exposes a live webcam server on all network interfaces without authentication and recommends overly broad camera-device permissions.

Install only after reviewing the webcam exposure risks. Change the preview server to bind to 127.0.0.1 or add authentication before running it, do not use chmod 666 for /dev/video0, and be careful with stored snapshots, automatic deletion, and any person-identification memory entries.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/web_preview.py:118
Finding
Unauthenticated Live Webcam Exposure on All Network Interfaces<![CDATA[ ## Vulnerability Details **File Location**: `scripts/web_preview.py`, lines 118-158 **Vulnerability Type**: Unauthenticated network exposure of sensitive webcam functionality **Risk Level**: High ### Vulnerable Code ```python class StreamHandler(BaseHTTPRequestHandler): def do_GET(self): if self.path == '/': self._serve_html() elif self.path == '/stream': self._serve_stream() elif self.path == '/snapshot': self._take_snapshot() else: self.send_error(404) def _serve_html(self): self.send_response(200) self.send_header('Content-Type', 'text/html') self.end_headers() self.wfile.write(HTML_PAGE.encode()) def _serve_stream(self): self.send_response(200) self.send_header('Content-Type', 'multipart/x-mixed-replace; boundary=frame') self.end_headers() while camera.running: frame = camera.get_frame() if frame is not None: _, buffer = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 85]) self.wfile.write(b'--frame\r\n') self.send_header('Content-Type', 'image/jpeg') self.send_header('Content-Length', len(buffer)) self.end_headers() self.wfile.write(buffer.tobytes()) self.wfile.write(b'\r\n') time.sleep(0.033) def _take_snapshot(self): frame = camera.get_frame() if frame is not None: filename = camera.save_snapshot(frame) self.send_response(200) self.send_header('Content-Type', 'text/plain') self.end_headers() self.wfile.write(f"Snapshot saved: {filename.name}".encode()) else: self.send_error(503, "No frame available") def log_message(self, format, *args): pass def main(): if not camera.start(): print("Fai ...[truncated 2129 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Bind the preview server to the loopback interface by default: ```python server = HTTPServer(("127.0.0.1", 8081), StreamHandler) ``` 2. If remote access is genuinely required: - Require strong authentication for every endpoint. - Serve the application through TLS. - Restrict access with host firewall rules or an explicit IP allowlist. - Place the service behind a hardened reverse proxy. - Avoid exposing the camera service directly to untrusted networks. 3. Change snapshot creation to an authenticated `POST` endpoint rather than a `GET` endpoint. 4. Add CSRF protection when browser-based authenticated access is supported. 5. Apply rate limits and connection limits to streaming and snapshot endpoints. 6. Display the actual bind address at startup and clearly warn users when the service is configured for non-loopback access. 7. Consider disabling remote snapshot creation unless it is explicitly enabled through a secure configuration option. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
SKILL.md:114
Finding
World-Readable and World-Writable Webcam Device Permission Recommendation<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 114-118 **Vulnerability Type**: Excessive local device permissions **Risk Level**: Medium ### Vulnerable Instructions ```markdown ### Permission denied ```bash sudo chmod 666 /dev/video0 ``` ``` ### Technical Analysis The recommended command changes `/dev/video0` to mode `0666`, granting read and write access to the device for the owner, group, and every other local user. This violates least-privilege principles because webcam access should normally be limited to a designated user or trusted device-access group. The command requires administrative privileges and weakens an operating-system access-control boundary globally for the affected device node. While device-node permissions can be recreated after device reconnection or reboot, the weakened permissions remain effective for as long as that node retains mode `0666`. ### Attack Path 1. The intended user encounters a camera permission error. 2. Following the Skill documentation, the user runs `sudo chmod 666 /dev/video0`. 3. The webcam device becomes accessible to every local account and process. 4. An untrusted local user or a compromised low-privilege process opens `/dev/video0`. 5. That process accesses the camera independently of the webcam-monitor Skill and outside the intended user's authorization boundary. ### Impact Assessment Any local user or process capable of opening the device can potentially capture webcam data, interfere with legitimate camera use, or manipulate supported device controls. This can result in unauthorized surveillance and denial of camera availability. The finding does not independently grant remote access, administrator privileges, or arbitrary code execution. Its scope is the local webcam device, but the privacy impact can be substantial because access crosses local account boundaries. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the recommendation to use mode `0666`. 2. Grant webcam access through the device's designated group, commonly `video`: ```bash sudo usermod -aG video "$USER" ``` The user should then sign out and back in, or otherwise refresh group membership. 3. Retain group-scoped device permissions such as `0660` rather than granting access to all users: ```bash sudo chgrp video /dev/video0 sudo chmod 660 /dev/video0 ``` 4. If USB passthrough recreates the device with incorrect permissions, use a narrowly scoped udev rule based on the camera's vendor and product identifiers. The rule should assign the device to a dedicated group and use mode `0660`. 5. Document how to inspect current ownership before changing it: ```bash ls -l /dev/video0 id ``` 6. If a dedicated service account runs the monitor, grant only that account or its dedicated group access to the camera. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The code clearly fits part of the description: it uses a webcam, detects motion, saves snapshots, and logs monitoring events. However, the declared purpose is significantly broader and includes WSL2 with USB/IP passthrough support, monitoring camera snapshots, auto-analyzing images with AI, and managing webcam-based security monitoring for specific camera setups. None of those broader or specialized capabilities appear in this code chunk. The actual behavior is a straightforward headless OpenCV motion detector operating on local camera device 0 with file logging and snapshot capture. Because key declared capabilities are absent and the description materially overstates what this code does, this should be flagged as a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The supplied code is clearly webcam-related, so it partially overlaps with the declared domain. However, the description emphasizes a motion detection and monitoring system for WSL2 with USB/IP passthrough, including automated image analysis and security/activity monitoring workflows. This code does not implement motion detection, automated monitoring logic, AI analysis, or any USB/IP/WSL2 configuration behavior. Instead, it provides a simple local web preview server with live streaming and a manual snapshot button. That is a materially narrower and different primary purpose than the declared description.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
### Permission denied
```bash
sudo chmod 666 /dev/video0
```

### Camera in use
Confidence
97% confidence
Finding
The command sudo chmod 666 /dev/video0 is an unsafe parameter recommendation because it applies an overly broad permission mode to a sensitive device. This weakens local security controls and can be abused by other local users or processes to access or disrupt the camera.

Missing User Warnings

High
Confidence
97% confidence
Finding
Exposing live camera data on all network interfaces without warning or access controls is dangerous because webcam imagery is highly sensitive and can reveal occupants, activities, and surroundings. In the context of a monitoring skill, this is more dangerous than a generic HTTP service because the data is inherently privacy-sensitive and the /snapshot endpoint can also persist images to disk remotely.

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill describes behaviors that involve writing files and exposing a web service, but it does not declare any explicit tool scope or permissions boundary. This increases the chance that an agent executes file-write or network-capable actions without clear user visibility or least-privilege constraints.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill advertises automatic deletion of snapshots without a clear warning that data will be destructively removed on a schedule. Users may unintentionally lose evidence or important records, especially in a security-monitoring context where snapshots may be needed later.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
### Permission denied
```bash
sudo chmod 666 /dev/video0
```

### Camera in use
Confidence
98% confidence
Finding
Setting /dev/video0 to mode 666 makes the webcam world-readable and world-writable, allowing any local process or user to access the camera device. In a monitoring skill, this is especially dangerous because it can enable unauthorized camera use, privacy compromise, or interference with capture operations.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
### Permission denied
```bash
sudo chmod 666 /dev/video0
```

### Camera in use
Confidence
98% confidence
Finding
Setting /dev/video0 to mode 666 makes the webcam world-readable and world-writable, allowing any local process or user to access the camera device. In a monitoring skill, this is especially dangerous because it can enable unauthorized camera use, privacy compromise, or interference with capture operations.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill encourages collecting, storing, and analyzing identifiable webcam images and personal traits without an explicit privacy warning, consent guidance, or retention safeguards. This can lead to privacy violations, unauthorized surveillance, and mishandling of sensitive biometric or identifying data.

Ssd 3

Medium
Confidence
95% confidence
Finding
The instructions explicitly tell users to store detailed person-identification data such as name, appearance, clothing, jewelry, and environment for AI analysis of webcam snapshots. In context, this is more dangerous because the skill is for persistent camera monitoring, making it easy to build sensitive profiles of identifiable individuals and enabling intrusive surveillance.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
#!/usr/bin/env python3.10
"""
Snapshot Watcher with Auto-Cleanup
Watches for new snapshots AND automatically deletes old ones
"""

import os
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
#!/usr/bin/env python3.10
"""
Snapshot Watcher with Auto-Cleanup
Watches for new snapshots AND automatically deletes old ones
"""

import os
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Missing User Warnings

Medium
Confidence
82% confidence
Finding
This code deletes snapshot and queue files via unlink() on a timer, which is a destructive operation. Although the file has a top-level docstring and logs that cleanup occurs, there is no confirmation step or stronger user-facing warning before irreversible deletion begins.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This code saves camera images into a persistent directory under the user's home folder, which affects user data/privacy. Although there is a runtime print after saving, there is no prior disclosure in the file's docstring, comments, or UI text warning that snapshots will be stored locally.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The server binds to 0.0.0.0, making the live webcam feed reachable from other hosts on the network rather than only the local machine. In a webcam-monitoring skill, this materially increases exposure because anyone with network access to the port can view sensitive camera data and trigger snapshot capture without authentication.

Intent-Code Divergence

Low
Confidence
98% confidence
Finding
The docstring claims the preview is served at localhost:8080, but the code actually listens on 0.0.0.0:8081. This mismatch can mislead users into believing the feed is local-only when it is in fact exposed on all interfaces, increasing the chance of accidental data exposure.

Static analysis

No suspicious patterns detected.