Back to skill

Security audit

Cameras

Security checks for vulnerabilities and agentic risk

Overview

This is a documentation-only camera skill, but it gives users unsafe examples for handling camera feeds, tokens, cloud image analysis, and continuous monitoring that deserve review before installation.

Review this skill carefully before installing. Only use it with cameras you own or administer, prefer HTTPS with verified certificates, avoid placing tokens in shell history, do not use curl -k with bearer tokens, clean up saved snapshots, and treat cloud vision examples as uploads of potentially sensitive surveillance images to third-party providers.

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
security-integration.md:100
Finding

TLS Certificate Verification Disabled for Authenticated UniFi Protect API Requests

Content
View full analysis

Vulnerability Details

File Location: security-integration.md:100-106
Vulnerability Type: Improper TLS certificate validation
Risk Level: High

Vulnerable Code

bash
# Get cameras
curl -k "https://unifi-protect:7443/proxy/protect/api/cameras" \
  -H "Authorization: Bearer $TOKEN"

# Snapshot
curl -k "https://unifi-protect:7443/proxy/protect/api/cameras/{id}/snapshot" \
  -o snapshot.jpg

Technical Analysis

The documented commands use the curl -k option, which disables validation of the server's TLS certificate. Consequently, the client does not verify that it is communicating with the intended UniFi Protect server.

The first request transmits an authorization bearer token over this unauthenticated TLS connection. Although traffic remains encrypted, an attacker able to intercept network communication can present an arbitrary certificate and establish a man-in-the-middle connection. The attacker could then read the bearer token and API response. The snapshot request is likewise vulnerable to interception or response manipulation.

Attack Path

  1. A user follows the documented command while connected to a network accessible to the attacker.
  2. The attacker obtains a network interception position through a compromised gateway, malicious access point, DNS poisoning, or ARP spoofing.
  3. The attacker redirects the UniFi Protect hostname or traffic to an attacker-controlled HTTPS endpoint.
  4. Because -k disables certificate verification, curl accepts the attacker's certificate without reporting a trust failure.
  5. The client sends the bearer token to the attacker-controlled endpoint.
  6. The attacker replays the captured token against the actual UniFi Protect API, subject to the token's validity and assigned privileges.
  7. The attacker can also intercept, replace, or collect camera metadata and snapshot content.

Impact Assessment

Successful exploitation can disclose the bea ...[truncated 391 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove -k from all curl commands.

  • Configure the client to trust the certificate authority that issued the UniFi Protect appliance certificate.

  • For a private CA, install its root certificate in the operating system trust store or pass it explicitly:

    bash
    curl --cacert /secure/path/unifi-ca.pem \
      "https://unifi-protect:7443/proxy/protect/api/cameras" \
      -H "Authorization: Bearer $TOKEN"
    
  • Where operationally appropriate, use certificate or public-key pinning in addition to normal certificate validation.

  • Use a narrowly scoped, short-lived API token and rotate it immediately if it may have been exposed.

  • Store tokens in a protected secret manager or environment variable, and prevent command tracing and logs from recording authorization headers.

  • Ensure both metadata and snapshot requests perform certificate validation.

T09 · Insecure Skill Coding Practices

Error
Location
security-integration.md:38
Finding

Home Assistant Bearer Token and Camera Data Transmitted over Plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: security-integration.md:38-48
Vulnerability Type: Cleartext transmission of sensitive information
Risk Level: High

Vulnerable Code

bash
curl -H "Authorization: Bearer $HA_TOKEN" \
  "http://homeassistant.local:8123/api/camera_proxy/camera.front_door" \
  -o snapshot.jpg

List all cameras:

bash
curl -H "Authorization: Bearer $HA_TOKEN" \
  "http://homeassistant.local:8123/api/states" | jq '.[] | select(.entity_id | startswith("camera."))'

Technical Analysis

Both commands transmit a Home Assistant bearer token using unencrypted HTTP. HTTP provides neither confidentiality nor server authentication. Any attacker capable of observing or modifying local network traffic can read the Authorization header, camera snapshots, entity state information, and API responses.

A bearer token grants access based on possession alone. An intercepted token can therefore be replayed without knowledge of a password or an additional cryptographic secret. The exact access available depends on the Home Assistant account and token permissions.

Attack Path

  1. A user executes one of the documented commands against the plaintext HTTP endpoint.
  2. An attacker gains visibility into the network path through a compromised router, malicious wireless access point, shared network, packet capture, or ARP spoofing.
  3. The request crosses the network without transport encryption.
  4. The attacker extracts the value of the Authorization: Bearer header and optionally captures returned camera images or entity states.
  5. The attacker replays the bearer token in requests to the reachable Home Assistant API.
  6. The attacker invokes any API operations authorized for that token until it is revoked or expires.
  7. If actively intercepting traffic, the attacker may also alter camera responses or API state data returned to the client.

Impact Assessment

Immediate impa ...[truncated 411 chars]

Remediation
View remediation

Remediation Suggestions

  • Replace the plaintext URL with an HTTPS endpoint that uses a valid, verified certificate:

    bash
    curl --fail --show-error \
      -H "Authorization: Bearer $HA_TOKEN" \
      "https://homeassistant.example/api/camera_proxy/camera.front_door" \
      -o snapshot.jpg
    
  • Configure Home Assistant directly for TLS or place it behind a correctly configured HTTPS reverse proxy.

  • Do not disable certificate validation to work around private-certificate errors; install the relevant private CA instead.

  • Use a narrowly scoped account or token where the deployment supports it, and avoid reusing administrative credentials.

  • Rotate tokens periodically and immediately revoke tokens suspected of interception.

  • Isolate Home Assistant and camera systems on a protected VLAN, but do not treat network segmentation as a replacement for TLS.

  • Update the documentation to warn that bearer tokens and camera data must not be sent over plaintext HTTP.

T09 · Insecure Skill Coding Practices

Warning
Location
capture.md:87
Finding

Camera Snapshots Persist in Temporary Storage without Cleanup

Content
View full analysis

Vulnerability Details

File Location: capture.md:87-104
Vulnerability Type: Insecure temporary-file lifecycle and sensitive-data retention
Risk Level: Medium

Vulnerable Code

python
def capture_webcam(device_index=0):
    """Capture snapshot from webcam"""
    with tempfile.NamedTemporaryFile(suffix='.jpg', delete=False) as f:
        output = f.name
    
    cmd = [
        'ffmpeg', '-y',
        '-f', 'avfoundation',  # or v4l2 on Linux
        '-framerate', '30',
        '-i', str(device_index),
        '-frames:v', '1',
        '-q:v', '2',
        output
    ]
    subprocess.run(cmd, capture_output=True)
    return output

Technical Analysis

NamedTemporaryFile is created with delete=False, and the function returns its path without defining any cleanup responsibility or deletion mechanism. Every invocation can therefore leave a captured camera image on disk indefinitely.

The standard temporary-file API creates the filename safely, so the demonstrated issue is not a predictable-name race. The security concern is persistent retention of potentially sensitive surveillance imagery. Files may remain after normal processing, errors, process termination, or repeated monitoring operations. They can also be incorporated into backups, disk images, or forensic recovery workflows.

Attack Path

  1. The capture function is invoked and creates a temporary JPEG with delete=False.
  2. ffmpeg writes a webcam image to the temporary path.
  3. A caller reads or processes the returned path but does not explicitly remove it.
  4. Repeated captures accumulate images in the temporary directory.
  5. A local user, compromised process, backup operator, or later attacker with access permitted by the file and directory permissions discovers the residual files.
  6. The attacker copies and reviews the snapshots, exposing people, locations, physical security conditions, or other private ...[truncated 667 chars]
Remediation
View remediation

Remediation Suggestions

  • Assign explicit cleanup ownership and delete the image in a finally block immediately after its consumer finishes.
  • Prefer an API that processes the snapshot within a managed context rather than returning an unmanaged persistent path.
  • Check the ffmpeg exit status before returning or processing the file.
  • Delete partial output when capture fails.
  • Apply restrictive file permissions and use a private temporary directory.
  • For highly sensitive deployments, configure encrypted temporary storage and prevent temporary images from entering backups.

Example managed lifecycle:

python
import os
import subprocess
import tempfile
from contextlib import contextmanager

@contextmanager
def capture_webcam(device_index=0):
    fd, output = tempfile.mkstemp(suffix=".jpg")
    os.close(fd)
    os.chmod(output, 0o600)

    try:
        subprocess.run(
            [
                "ffmpeg", "-y",
                "-f", "avfoundation",
                "-framerate", "30",
                "-i", str(device_index),
                "-frames:v", "1",
                "-q:v", "2",
                output,
            ],
            capture_output=True,
            check=True,
        )
        yield output
    finally:
        try:
            os.remove(output)
        except FileNotFoundError:
            pass

Callers should consume the image only inside the context so cleanup occurs on success and failure.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (15)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
60% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · security-integration.md (reported line 56)May include surrounding context.

Get recent events:

bash
curl "http://frigate:5000/api/events?limit=10"

Get snapshot of event:

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · security-integration.md (reported line 87)May include surrounding context.

Requires Device Access API ($5 one-time fee):

  1. Create project at device-access.google.com
  2. Link Nest account
  3. OAuth2 flow for access token
  4. Use REST API for snapshots
bash

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill provides clear instructions and code for capturing webcam images and recordings, including agent-integration examples, but does not mention user consent, authorization, or privacy safeguards. In an agent context, this omission makes covert or non-consensual camera access easier to operationalize and increases the risk of privacy violations or surveillance misuse.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file documents DSLR and mirrorless camera control over USB/WiFi, including studio and tethered photography workflows, which does not align with a skill described as connecting to security cameras for snapshots and video feeds. This scope mismatch increases the chance that an agent using the skill will access or control unintended devices, perform unsafe actions, or mislead operators about the skill’s purpose and permissions.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · photography-control.md (reported line 13)May include surrounding context.

brew install gphoto2

Linux

sudo apt install gphoto2

text

### Basic Commands

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The commands shown capture photos, download files, and modify camera settings, but the documentation does not warn that these actions change device state and write data to the local system. Users or downstream agents may execute them assuming they are read-only, causing unintended captures, configuration changes, or data sprawl.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Studio product photography, focus stacking, and artistic remote-trigger workflows are unrelated to a security-camera skill and introduce extra capture/control capabilities beyond the expected operational scope. In a security context, such unjustified functionality can enable unauthorized image capture, device manipulation, or operator confusion about what actions are legitimate.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation recommends killall PTPCamera without clearly warning that it terminates a system service/process on macOS. In an agentic or copy-paste setting, this can disrupt other camera-dependent applications or user workflows and normalizes destructive troubleshooting steps without guardrails.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The example captures a security camera snapshot and sends it to an external vision model without an explicit warning that sensitive surveillance imagery is uploaded off-device. In the context of security cameras, this can expose people, vehicles, locations, and other private details to a third-party service, creating privacy, compliance, and data-handling risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The Google Cloud Vision example reads image contents and submits them to Google's API without clearly warning that security camera images leave the local environment. Because the skill is specifically about surveillance feeds, users may unknowingly upload highly sensitive footage, increasing privacy and regulatory exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The AWS Rekognition sample sends raw image bytes to AWS without clearly informing the user that surveillance imagery is being transmitted to an external cloud service. In a security camera context, that omission can lead to unintentional disclosure of sensitive footage and noncompliant handling of personal data.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The privacy guidance says to minimize cloud use and send snapshots only when needed, yet the file prominently demonstrates sending camera snapshots to Anthropic, Google Cloud Vision, and AWS Rekognition. This is more than incomplete documentation: the privacy-oriented guidance is in tension with the concrete examples that externalize security camera imagery for analysis.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The examples show how to pull live camera snapshots and enumerate camera entities without any privacy, consent, retention, or access-control guidance. In a camera/surveillance skill, this omission is meaningful because it normalizes access to highly sensitive visual data and may lead downstream agents or users to collect or expose surveillance imagery without appropriate safeguards.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · security-integration.md (reported line 56)May include surrounding context.

Get recent events:

bash
curl "http://frigate:5000/api/events?limit=10"

Get snapshot of event:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The 'Typical Agent Flow' describes continuous monitoring, image analysis, and automated alerts for camera feeds with no warning about surveillance legality, consent, or privacy boundaries. Because this skill is specifically about security cameras, the context makes the omission more dangerous: it operationalizes automated monitoring of people and property without guardrails.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.