Back to skill

Security audit

Video Reader

Security checks across malware telemetry and agentic risk

Overview

This appears to be a real video-analysis skill, but it needs Review because it can fetch remote videos, send sensitive media-derived data to configured services, and leave transcripts, frames, logs, and downloads on disk.

Install only if you are comfortable with the skill downloading videos, extracting frames/audio, using sub-agents, and retaining local artifacts. Before using it on sensitive videos, review WHISPER_API_KEY, WHISPER_BASE_URL, VISION_* and proxy settings, prefer local transcription where possible, and run the cleanup tool for cached downloads, frame images, memory, and logs.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (22)

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Content
import shutil
    plist_dst.parent.mkdir(parents=True, exist_ok=True)
    shutil.copy2(plist_src, plist_dst)
    os.system(f"launchctl load {plist_dst}")
    print(f"✅ Installed launchd service: {plist_dst}")
Confidence
97% confidence
Finding
os.system(f"launchctl load {plist_dst}")

Tainted flow: 'proxies' from os.environ.get (line 47, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
tracer.log("api_call", model=model, base_url=base_url, proxy=bool(proxy))

        with open(tmp, "rb") as audio_file:
            resp = requests.post(
                f"{base_url}/audio/transcriptions",
                headers={"Authorization": f"Bearer {api_key}"},
                files={"file": ("audio.wav", audio_file, "audio/wav")},
Confidence
89% confidence
Finding
resp = requests.post( f"{base_url}/audio/transcriptions", headers={"Authorization": f"Bearer {api_key}"}, files={"file": ("audio.wav", audio

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill's declared purpose substantially understates its broader behavior, including downloading remote content, modifying environment/configuration, installing services, and running local servers. This mismatch is dangerous because users and reviewers may authorize the skill for simple video QA while it performs host-level changes and networked operations that expand the attack surface and could enable persistence or unintended data exposure.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
This setup script installs a macOS LaunchAgent and loads it automatically, creating persistence beyond what users may expect from a local transcription helper. In an agent skill context, persistence materially increases risk because the component will restart on login and continue running even after the user stops actively using the skill.

Intent-Code Divergence

Low
Confidence
88% confidence
Finding
The function description understates behavior: it does not merely update runtime config, it may create or overwrite the parent project's .env file. Silent modification of configuration files can break existing setups or redirect future requests to a different service endpoint without the user's informed consent.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The README explicitly states that the tool can download videos from remote platforms and that a Whisper model is automatically downloaded on first run, but it does not give a clear privacy/security warning about outbound network access, third-party transfers, and persistent local storage under ~/.videoarm/. In an agent skill context, this matters because users may invoke the skill expecting local analysis while it silently reaches external services or stores potentially sensitive media/transcripts on disk, increasing privacy and compliance risk.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The skill instructs the agent to store transcripts, questions, and analysis results in a persistent file under /tmp without warning the user. Even though /tmp is temporary in name, its contents can persist for the session or longer and may be readable by other local processes depending on host configuration, exposing potentially sensitive video-derived content.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The skill supports downloading videos from arbitrary external URLs and even specifies proxy-based network access, but does not warn users that their request triggers outbound connections and remote content retrieval. This is dangerous because it can leak user intent or metadata to third parties, pull untrusted media into the local environment, and violate network or privacy expectations in restricted environments.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This function uploads extracted audio from the user's video to an external transcription service without any explicit user-facing consent, warning, or disclosure in the tool flow shown here. In a video-analysis skill, audio may contain sensitive conversations, credentials, or personal data, so silent exfiltration to a third party creates a real privacy and compliance risk.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The logger persists arbitrary tool payloads, results, and errors to disk in JSONL and text logs, and this skill processes video, frame-analysis, and audio-transcription data that may contain sensitive user content. Because there is no consent flow, redaction policy, or data minimization before writing, private prompts, transcripts, file paths, or extracted content may be stored locally and exposed to other local users, backups, or later compromise.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The code sends base64-encoded frame image data and prompt text to Anthropic's external API, which is a real data-exfiltration/privacy boundary crossing. In a video question-answering skill, frames may contain sensitive visual content and prompts may include user data, yet this file contains no consent, disclosure, data-classification check, or redaction/minimization before transmission.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The code writes user-provided frame data to disk as temporary image files and then passes the file path to a spawned sub-agent, but there is no indication in this component of user notice, consent, minimization, or lifecycle guarantees beyond deleting the final image path. In a video-question-answering skill, frames may contain sensitive visual data, so forwarding them to another agent/process increases privacy and data-handling risk, especially because temporary files may persist if the process crashes or if the downstream wrapper transmits them to external services.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script modifies the project's .env automatically and without confirmation. In this context that can change application behavior globally, including API base URLs and model selection, which is risky because users may not notice their environment has been altered.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The script installs and immediately loads a LaunchAgent without prior consent. Unprompted persistence is security-sensitive behavior because it causes code to run automatically on future logins, which is more dangerous in a tool/agent ecosystem where users may expect one-time setup only.

Unvalidated Output Injection

High
Category
Output Handling
Content
print()
        return

    result = subprocess.run(
        ["yt-dlp", "-f", "bestvideo[height<=1080]+bestaudio/best[height<=1080]",
         "--merge-output-format", "mp4", "-o", str(out), args.url],
        capture_output=True, text=True, timeout=300,
Confidence
86% confidence
Finding
subprocess.run( ["yt-dlp", "-f", "bestvideo[height<=1080]+bestaudio/best[height<=1080]", "--merge-output

Unvalidated Output Injection

High
Category
Output Handling
Content
if tracer:
        tracer.log("download_start", url=url)

    result = subprocess.run(
        [
            "yt-dlp",
            "-f", "bestvideo[height<=1080]+bestaudio/best[height<=1080]",
Confidence
83% confidence
Finding
subprocess.run( [ "yt-dlp", "-f", "bestvideo[height<=1080]+bestaudio/best[height<=1080]", "--merge-output

Unvalidated Output Injection

High
Category
Output Handling
Content
def get_video_meta(video_path: str) -> dict:
    """Return fps, total_frames, duration, has_audio for a video file."""
    result = subprocess.run(
        ["ffprobe", "-v", "quiet", "-print_format", "json",
         "-show_format", "-show_streams", video_path],
        capture_output=True, text=True, timeout=15,
Confidence
85% confidence
Finding
subprocess.run( ["ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", video_path], capture_output

Unpinned Dependencies

Low
Category
Supply Chain
Content
opencv-python>=4.8
numpy>=1.24
requests>=2.31
python-dotenv>=1.0
Confidence
95% confidence
Finding
opencv-python>=4.8

Unpinned Dependencies

Low
Category
Supply Chain
Content
opencv-python>=4.8
numpy>=1.24
requests>=2.31
python-dotenv>=1.0
faster-whisper>=1.0
Confidence
95% confidence
Finding
numpy>=1.24

Unpinned Dependencies

Low
Category
Supply Chain
Content
opencv-python>=4.8
numpy>=1.24
requests>=2.31
python-dotenv>=1.0
faster-whisper>=1.0
Confidence
95% confidence
Finding
requests>=2.31

Unpinned Dependencies

Low
Category
Supply Chain
Content
opencv-python>=4.8
numpy>=1.24
requests>=2.31
python-dotenv>=1.0
faster-whisper>=1.0
Confidence
90% confidence
Finding
python-dotenv>=1.0

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy>=1.24
requests>=2.31
python-dotenv>=1.0
faster-whisper>=1.0
Confidence
94% confidence
Finding
faster-whisper>=1.0

VirusTotal

64/64 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

No suspicious patterns detected.