Back to skill

Security audit

Ai Video Gen 1.0.0

Security checks for vulnerabilities and agentic risk

Overview

The skill fits AI video generation overall, but it overstates provider support and can send user prompts/media to third-party services with weak disclosure and safeguards.

Review this skill before installing. Use only non-sensitive prompts and media, verify which provider will receive your data, avoid the Runway option unless it is fixed, run it in an isolated environment, and pin dependencies if you choose to proceed.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
images_to_video.py:25
Finding

Predictable Temporary File Allows Symlink-Based File Overwrite

Content
View full analysis

Vulnerability Details

File Location: images_to_video.py, lines 25–30 and 54–56
Vulnerability Type: Unsafe predictable temporary file
Risk Level: Medium

python
# Create temporary file list
file_list_path = Path('filelist.txt')
with open(file_list_path, 'w') as f:
    for img in image_files:
        duration = 1.0 / fps
        f.write(f"file '{Path(img).absolute()}'\n")
        f.write(f"duration {duration}\n")
python
finally:
    # Clean up temp file
    if file_list_path.exists():
        file_list_path.unlink()

Technical Analysis

The script uses the fixed filename filelist.txt in its current working directory and opens it using write-and-truncate semantics. It does not create the file atomically, verify that it is a regular file, reject symbolic links, or assign a unique name.

A local attacker with write access to the working directory can pre-create filelist.txt as a symbolic link to another file writable by the victim process. When the Skill runs, open(..., 'w') follows the link and truncates the linked target before writing the FFmpeg manifest. The cleanup operation may then unlink the symbolic link.

Concurrent executions also use the same path. One process can overwrite or remove another process's manifest, causing unintended inputs, corrupted output, or failures.

Attack Path

  1. The attacker identifies a directory in which a more privileged user or service will execute the script.
  2. The attacker creates filelist.txt as a symbolic link to a file writable by the victim process.
  3. The victim invokes images_to_video.py from that directory.
  4. The script follows the symbolic link when opening filelist.txt with truncation enabled.
  5. The target file is truncated and replaced with FFmpeg manifest content.
  6. The script subsequently attempts to remove the predictable path during cleanup.

Impact Assessment

The vulnerability can overwrite ...[truncated 441 chars]

Remediation
View remediation

Remediation Suggestions

  • Create the manifest using tempfile.NamedTemporaryFile or tempfile.mkstemp with a unique, securely generated filename.
  • Place temporary files in a private temporary directory with restrictive permissions.
  • Create files atomically and do not follow symbolic links where the platform supports O_NOFOLLOW.
  • Verify that any existing path is a regular file owned by the current process before using or deleting it.
  • Keep cleanup in a finally block, but only remove the exact unique file created by the current invocation.
  • Avoid running the media conversion process with elevated privileges.

Example hardening pattern:

python
import os
import tempfile

fd, manifest_path = tempfile.mkstemp(
    prefix="ffmpeg_concat_",
    suffix=".txt",
    text=True
)

try:
    with os.fdopen(fd, "w", encoding="utf-8") as manifest:
        # Write validated entries.
        pass
finally:
    Path(manifest_path).unlink(missing_ok=True)

T09 · Insecure Skill Coding Practices

Warning
Location
images_to_video.py:27
Finding

FFmpeg Concat Manifest Injection Through Unescaped Filenames

Content
View full analysis

Vulnerability Details

File Location: images_to_video.py, lines 27–40
Vulnerability Type: Injection into an FFmpeg concat manifest
Risk Level: Medium

python
with open(file_list_path, 'w') as f:
    for img in image_files:
        duration = 1.0 / fps
        f.write(f"file '{Path(img).absolute()}'\n")
        f.write(f"duration {duration}\n")

# FFmpeg command
cmd = [
    'ffmpeg', '-y',
    '-f', 'concat',
    '-safe', '0',
    '-i', str(file_list_path),
    '-vsync', 'vfr',
    '-pix_fmt', 'yuv420p',
    '-crf', str(crf),
    output_path
]

Technical Analysis

User-supplied image paths are inserted directly into FFmpeg concat-demuxer syntax. Although FFmpeg is invoked through an argument list rather than a shell, the generated text file is itself interpreted by a separate parser.

Filenames containing single quotes, backslashes, carriage returns, or newline characters can break out of the intended file '...' entry and introduce additional concat directives. Input validation only verifies that the supplied path exists; it does not reject parser-control characters or ensure that the resolved path is an approved regular image file.

The use of -safe 0 disables FFmpeg's safe-path restrictions and permits absolute paths. This increases the potential scope of injected entries by allowing FFmpeg to access other resources available to the executing process.

Attack Path

  1. The attacker creates or supplies an existing file whose filename contains FFmpeg concat control characters, such as a quote or newline.
  2. The attacker causes that path to be passed through the --images argument.
  3. The script's existence check succeeds because the crafted path exists.
  4. The path is written into filelist.txt without concat-format escaping.
  5. FFmpeg parses attacker-controlled text as additional manifest syntax.
  6. FFmpeg attempts to open resources identified by the injected dire ...[truncated 816 chars]
Remediation
View remediation

Remediation Suggestions

  • Avoid constructing a text concat manifest from untrusted filenames where possible.
  • Reject paths containing newline, carriage-return, null, quote, or other concat-parser control characters.
  • Apply escaping that strictly follows FFmpeg concat-demuxer rules rather than shell-escaping rules.
  • Resolve each path and require it to be a regular file beneath an explicitly approved input directory.
  • Validate expected image extensions and, where practical, decode each image before supplying it to FFmpeg.
  • Remove -safe 0 unless absolute or otherwise unsafe paths are strictly required.
  • Restrict the FFmpeg process's filesystem and network access through sandboxing, containers, or operating-system access controls.
  • Run FFmpeg as an unprivileged account and keep it updated against decoder vulnerabilities.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Open-Ended and Unhashed Third-Party Dependencies Create Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: requirements.txt, lines 1–5
Vulnerability Type: Non-reproducible dependency resolution
Risk Level: Low

text
openai>=1.0.0
replicate>=0.20.0
requests>=2.31.0
pillow>=10.0.0
python-dotenv>=1.0.0

Technical Analysis

Every dependency is declared with an open-ended minimum version and without package hashes. A future installation may therefore retrieve versions substantially newer than those reviewed by the project author.

This does not establish that any listed package is currently malicious. However, it makes builds non-reproducible and expands trust to all future matching releases and their changing transitive dependency trees. If a future release or dependency is compromised, the unreviewed code can execute in the user's environment during installation or normal Skill operation.

Attack Path

  1. A user follows the documented command pip install -r requirements.txt.
  2. The package index resolves the newest releases satisfying the open-ended constraints.
  3. A resolved package or transitive dependency differs from the version originally reviewed.
  4. If that release is malicious or compromised, its installation or runtime behavior executes with the user's privileges.
  5. The compromised dependency can access data and credentials available to the Python process, including configured AI-provider API keys.

This exploitation path is conditional on a future package, package-index account, or transitive dependency being compromised; no such compromise was confirmed during this static audit.

Impact Assessment

Dependency code executes with the same privileges as the Skill. A compromised package could read environment variables, access local files, make network requests, alter generated output, or execute arbitrary code.

The potential technical impact is high, but the finding is rated Low because the reviewed dependency names are legiti ...[truncated 175 chars]

Remediation
View remediation

Remediation Suggestions

  • Pin every direct and transitive dependency to an exact reviewed version.
  • Generate and commit a lock file using a dependency management tool such as pip-tools, Poetry, or uv.
  • Record cryptographic hashes and install with pip --require-hashes.
  • Review and test dependency upgrades through a controlled update process.
  • Use automated vulnerability and supply-chain monitoring.
  • Install dependencies inside an isolated virtual environment or container.
  • Restrict runtime access to secrets and files so that dependencies receive only the privileges required for the selected provider and operation.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (33)

Tainted flow: 'image_url' from os.getenv (line 49, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The code downloads image content from a URL returned by an external service without validating the hostname, scheme, size, or content type. If that upstream response is malicious or compromised, this can trigger SSRF-style fetches to unexpected locations or unbounded downloads to local disk.

Content

Scanner excerpt · generate_video.py (reported line 53)May include surrounding context.

python
# Download image
        img_path = self.output_dir / f"image_{int(time.time())}.png"
        img_data = requests.get(image_url).content
        with open(img_path, 'wb') as f:
            f.write(img_data)

Tainted flow: 'headers' from os.getenv (line 94, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · generate_video.py (reported line 106)May include surrounding context.

python
"prompt": prompt or "animate this image"
        }
        
        response = requests.post(
            "https://api.lumalabs.ai/dream-machine/v1/generations",
            headers=headers,
            json=data

Tainted flow: 'headers' from os.getenv (line 94, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · generate_video.py (reported line 119)May include surrounding context.

python
# Poll for completion
        while True:
            status = requests.get(
                f"https://api.lumalabs.ai/dream-machine/v1/generations/{generation_id}",
                headers=headers
            ).json()

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 · QUICK_START.md (reported line 16)May include surrounding context.

md
1. Go to https://lumalabs.ai
2. Sign up (has free tier!)
3. Get API key from dashboard

**Cost:** FREE for first 30 videos/month

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · QUICK_START.md (reported line 26)May include surrounding context.

bash
cd skills/ai-video-gen
copy .env.example .env

Edit .env and add:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · README.md (reported line 28)May include surrounding context.

bash
cd skills/ai-video-gen
copy .env.example .env

Edit .env and add:

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · README.md (reported line 29)May include surrounding context.

bash
copy .env.example .env
notepad .env

Minimum required:

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented behavior claims a much broader AI-video pipeline than the detected implementation supports, including third-party integrations and media-generation features that appear absent. This mismatch is dangerous because users and agents may trust the description, supply sensitive prompts, API keys, or media, and make execution decisions under false assumptions about what the skill actually does.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README instructs users to configure API keys and use multiple external AI providers, and it emphasizes pricing, but it does not explicitly warn that prompts, images, audio, and other media may be transmitted to third-party services for processing. In a skill that automates media generation and voiceover, this omission can lead users to unknowingly send sensitive content to external vendors and incur usage-based charges.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill advertises and instructs use of capabilities that imply environment access, file writes, network calls, and shell execution, but it does not declare any tool scope or permission boundaries. This is dangerous because an agent or reviewer cannot tell what external effects are authorized, increasing the risk of over-privileged execution, secret exposure, uncontrolled network egress, or unsafe command execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill encourages use of multiple third-party AI and video providers but does not warn that prompts, images, narration text, and generated media may be transmitted to external services. This creates a privacy and compliance risk because users may unknowingly send sensitive content, proprietary media, or regulated data to vendors with different retention, training, or sharing practices.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

User-provided text is transmitted to OpenAI's TTS API without any explicit notice or consent prompt at the point of use. In a skill that may process arbitrary prompts, this can cause unintended disclosure of sensitive or proprietary text to an external service, creating privacy and compliance risk rather than direct code-execution risk.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill description claims Runway support even though the implementation substitutes LumaAI. In a tool that sends prompts, images, and media to external AI vendors, misleading provider claims materially increase privacy and compliance risk because users cannot accurately control where their data goes.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code transmits image_path in the JSON request body to LumaAI without clear disclosure to the user. Even if it is only a local path string, it can reveal local filesystem structure or usernames and indicates data is being sent to an external service without explicit consent.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 · generate_video.py (reported line 106)May include surrounding context.

python
"prompt": prompt or "animate this image"
        }
        
        response = requests.post(
            "https://api.lumalabs.ai/dream-machine/v1/generations",
            headers=headers,
            json=data

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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 · generate_video.py (reported line 106)May include surrounding context.

python
"prompt": prompt or "animate this image"
        }
        
        response = requests.post(
            "https://api.lumalabs.ai/dream-machine/v1/generations",
            headers=headers,
            json=data

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 · generate_video.py (reported line 107)May include surrounding context.

python
}
        
        response = requests.post(
            "https://api.lumalabs.ai/dream-machine/v1/generations",
            headers=headers,
            json=data
        )

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 · generate_video.py (reported line 120)May include surrounding context.

python
}
        
        response = requests.post(
            "https://api.lumalabs.ai/dream-machine/v1/generations",
            headers=headers,
            json=data
        )

Tainted flow: 'generation_id' from requests.post (line 115, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · generate_video.py (reported line 119)May include surrounding context.

python
# Poll for completion
        while True:
            status = requests.get(
                f"https://api.lumalabs.ai/dream-machine/v1/generations/{generation_id}",
                headers=headers
            ).json()

Tainted flow: 'video_url' from requests.get (line 125, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
84% confidence
Finding

The script downloads a video from a URL taken directly from a prior network response and writes it to disk without any validation or size limits. A malicious or compromised API response could redirect the program to fetch unexpected internal or external resources or consume excessive storage/bandwidth.

Content

Scanner excerpt · generate_video.py (reported line 135)May include surrounding context.

python
# Download video
        video_path = self.output_dir / f"video_{int(time.time())}.mp4"
        video_data = requests.get(video_url).content
        with open(video_path, 'wb') as f:
            f.write(video_data)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Voiceover text is sent to OpenAI TTS with no explicit user-facing disclosure that the content leaves the local environment. Prompts and narration may contain sensitive or proprietary information, so undisclosed third-party transmission creates privacy and compliance exposure.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · generate_video.py (reported line 180)May include surrounding context.

python
output_path
        ]
        
        result = subprocess.run(cmd, capture_output=True, text=True)
        
        if result.returncode != 0:
            raise Exception(f"FFmpeg error: {result.stderr}")

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The CLI advertises a Runway option but silently routes the request to LumaAI instead. This can cause user data and prompts to be transmitted to a different third-party provider than the user selected, creating a consent, privacy, and trust violation.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · add_voiceover.py (reported line 70)May include surrounding context.

python
]
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, check=True)
        print(f"✅ Video created: {output_path}")
        return output_path
    except subprocess.CalledProcessError as e:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · images_to_video.py (reported line 47)May include surrounding context.

python
]
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, check=True)
        print(f"✅ Video created: {output_path}")
        return output_path
    except subprocess.CalledProcessError as e:

Static analysis

No suspicious patterns detected.