Back to skill

Security audit

Ai Video Workflow

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent AI-video workflow, but its bundled media download tools include under-scoped arbitrary URL and file-write behavior that should be reviewed before installation.

Install only if you are comfortable giving the skill network access to stock-media providers and local write access for downloaded assets. Use provider API keys with limited privileges, keep config.json local, avoid passing untrusted URLs or output paths into the download commands, and prefer a version that restricts downloads to validated provider asset URLs and a dedicated media output directory.

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/pexels.ts:108
Finding

Unrestricted URL Download and Arbitrary File Write in Pexels CLI

Content
View full analysis
{ const resp = await fetch(url, { headers: { "User-Agent": "PexelsCLI/0.1" }, }); if (!resp.ok) { console.error(`Download failed - HTTP ${resp.status}`); process.exit(1); } const buf = await resp.arrayBuffer(); await Bun.write(output, new Uint8Array(buf)); console.error(`Downloaded: ${output}`); } ``` ```typescript async function download(flags: Record) { if (!flags["--url"]) { console.error("Error: --url is required"); process.exit(1); } if (!flags["--output"]) { console.error("Error: --output is required"); process.exit(1); } await downloadFile(flags["--url"], flags["--output"]); } ``` ### Technical Analysis The public `download` command passes attacker-controlled `--url` and `--output` values directly to `fetch()` and `Bun.write()`. The implementation does not: - Require HTTPS. - Restrict downloads to Pexels-controlled media hosts. - Block loopback, private, link-local, or cloud metadata addresses. - validate redirect destinations. - Restrict output to an approved workspace directory. - Prevent writes through symbolic links. - Prevent replacement of existing sensitive files. - Enforce response-size, timeout, or disk-consumption limits. This behavior exceeds the minimum privileges required for downloading Pexels assets. Although the command is described as a Pexels downloader, it functions as a general-purpose network retrieval and file-write primitive. ### Attack Path 1. An attacker supplies a crafted media URL through a prompt, task description, or untrusted workflow input. 2. The agent invokes: `bun ./scripts/pexels.ts download --url "ATTACKER_SELECTED_UR ...[truncated 1210 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/pixabay.ts:91
Finding

Unrestricted URL Download and Arbitrary File Write in Pixabay CLI

Content
View full analysis
{ const resp = await fetch(url); if (!resp.ok) { console.error(`Download failed – HTTP ${resp.status}`); process.exit(1); } const buf = await resp.arrayBuffer(); await Bun.write(output, new Uint8Array(buf)); console.error(`Downloaded: ${output}`); } ``` ```typescript async function download(flags: Record) { if (!flags["--url"]) { console.error("Error: --url is required"); process.exit(1); } if (!flags["--output"]) { console.error("Error: --output is required"); process.exit(1); } await downloadFile(flags["--url"], flags["--output"]); } ``` ### Technical Analysis The Pixabay `download` command accepts an arbitrary URL and destination path and passes them directly to `fetch()` and `Bun.write()`. No validation limits the URL to Pixabay media infrastructure. The implementation also does not reject internal address ranges, inspect redirect destinations, constrain output paths, prevent symbolic-link writes, or limit response size. As a result, a command intended to download Pixabay media can access any network destination reachable by the process and write the response to any writable path. Buffering the entire response through `arrayBuffer()` further permits memory exhaustion before the file is written. ### Attack Path 1. An attacker causes an agent to treat an attacker-selected URL as a Pixabay asset. 2. The agent invokes the `download` command with that URL and an attacker-selected output path. 3. The script sends a request to the selected destination. This can include local or internal services if they are reachable from the runtime. 4. Redirects may cause the request to r ...[truncated 861 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/freesound.ts:87
Finding

Freesound API Token Forwarded to an Unvalidated Download Host

Content
View full analysis
{ const headers: Record = { "User-Agent": "FreesoundCLI/0.1" }; if (token) { headers["Authorization"] = `Token ${token}`; } const resp = await fetch(url, { headers }); if (!resp.ok) { console.error(`Download failed – HTTP ${resp.status}`); process.exit(1); } const buf = await resp.arrayBuffer(); await Bun.write(output, new Uint8Array(buf)); console.error(`Downloaded: ${output}`); } ``` ```typescript async function downloadSound(flags: Record) { const token = getApiToken(flags); const id = flags["--id"]; if (!id) { console.error("Error: --id is required"); process.exit(1); } if (!flags["--output"]) { console.error("Error: --output is required for download"); process.exit(1); } // Get download URL const data = await apiRequest(`/sounds/${id}/download/`, {}, token); if (!data.download_link) { console.error("Error: No download link returned. Note: OAuth2 may be required for original file downloads."); process.exit(1); } await downloadFile(data.download_link, flags["--output"], token); } ``` ### Technical Analysis The `download-original` command retrieves `download_link` from a Freesound API response and passes it to `downloadFile()` together with the API token. `downloadFile()` then attaches the token as an `Authorization` header without validating the destination URL. The initial API request correctly targets the declared HTTPS Freesound API. The vulnerability occurs in the subsequent authenticated download because the code assumes that every returned URL is safe to receive the credential. There is no exact hostname a ...[truncated 1798 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The Pixabay-related behavior includes downloading arbitrary remote files to local paths, again without explicit permission scoping in the skill metadata. In an agent setting, that can be exploited for untrusted content ingestion, storage abuse, path misuse, or turning the skill into a general-purpose fetch-and-save mechanism beyond its stated purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The Pixabay-related behavior includes downloading arbitrary remote files to local paths, again without explicit permission scoping in the skill metadata. In an agent setting, that can be exploited for untrusted content ingestion, storage abuse, path misuse, or turning the skill into a general-purpose fetch-and-save mechanism beyond its stated purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The Pixabay-related behavior includes downloading arbitrary remote files to local paths, again without explicit permission scoping in the skill metadata. In an agent setting, that can be exploited for untrusted content ingestion, storage abuse, path misuse, or turning the skill into a general-purpose fetch-and-save mechanism beyond its stated purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The Pixabay-related behavior includes downloading arbitrary remote files to local paths, again without explicit permission scoping in the skill metadata. In an agent setting, that can be exploited for untrusted content ingestion, storage abuse, path misuse, or turning the skill into a general-purpose fetch-and-save mechanism beyond its stated purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The Pixabay-related behavior includes downloading arbitrary remote files to local paths, again without explicit permission scoping in the skill metadata. In an agent setting, that can be exploited for untrusted content ingestion, storage abuse, path misuse, or turning the skill into a general-purpose fetch-and-save mechanism beyond its stated purpose.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 56)May include surrounding context.

md
bun ./scripts/pexels.ts search-videos --query "city skyline" --orientation portrait --per-page 10

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 62)May include surrounding context.

md
bun ./scripts/pexels.ts search-videos --query "city skyline" --orientation portrait --per-page 10

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 57)May include surrounding context.

md
bun ./scripts/pixabay.ts search-videos --query "ocean waves" --per-page 10

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 58)May include surrounding context.

md
bun ./scripts/jamendo.ts search --query "background" --vocalinstrumental instrumental --limit 5

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 59)May include surrounding context.

md
bun ./scripts/freesound.ts search --query "whoosh" --page-size 10

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The manifest says this skill is for creating complete AI-generated videos from scripts, briefs, products, or articles, but this file implements a standalone CLI for searching, retrieving, streaming, and downloading royalty-free music from Jamendo. Music asset lookup may support video production in a broad sense, but this script's functionality is centered on external music catalog operations rather than AI video generation or script-to-video workflows.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill instructs use of external APIs, local config files, and downloader scripts, which implies network and environment access, but it declares no corresponding tool scope or permissions. This creates hidden capability risk: an agent or reviewer may authorize the skill under false assumptions, enabling external calls or secret-dependent behavior without explicit disclosure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This file forces the skill's operational instructions and required prompts into Chinese throughout the document. The policy requires flagging language or locale constraints when the skill does not offer the user a language choice or clearly justify the restriction.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes a workflow for generating short videos, narration videos, and script-to-video outputs. In contrast, this file is a standalone CLI for querying the Freesound API, fetching comments/similar sounds, and downloading audio assets, which is a materially different operational scope than video generation itself.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The CLI help advertises only preview downloads, but the dispatcher also exposes an undocumented 'download-original' command that retrieves the original file using an authenticated download link. Hidden functionality that expands access beyond documented behavior is dangerous because users and reviewers may not realize the tool can fetch full source assets, increasing the risk of unauthorized use, policy bypass, or accidental handling of higher-risk content than expected.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · scripts/jamendo.ts (reported line 17)May include surrounding context.

ts
import * as fs from "fs";
import { formatJamendoAlbums, formatJamendoArtists, formatJamendoTracks } from "./formatters";

const BASE_URL = "https://api.jamendo.com/v3.0";
const CONFIG_FILE = path.join(import.meta.dir, "..", "config.json");

// ── helpers ──────────────────────────────────────────────────────────────

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The download command fetches third-party audio files from Jamendo and writes them to arbitrary output paths, creating a distinct asset acquisition capability. The manifest does not mention music sourcing, stock media retrieval, or third-party media downloads, so this capability is broader than the stated purpose of generating videos from provided inputs.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The file header and help text present this as a Pexels-specific downloader, but the implementation actually downloads arbitrary URLs. This mismatch increases the chance that downstream users, agents, or reviewers trust the command more than they should, enabling misuse of the generic fetch capability in contexts where only vetted Pexels assets were expected.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 · scripts/pexels.ts (reported line 15)May include surrounding context.

ts
import * as fs from "fs";
import { formatPexelsPhotos, formatPexelsVideos } from "./formatters";

const BASE_URL = "https://api.pexels.com/v1";
const CONFIG_FILE = path.join(import.meta.dir, "..", "config.json");

// ── helpers ──────────────────────────────────────────────────────────────

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The download command accepts any user-supplied URL and fetches it without restricting the destination to Pexels-owned domains or approved asset URLs. In an agent/workflow context, this can be abused for server-side request forgery–style behavior, internal network access, or downloading unexpected content under the guise of a Pexels helper.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The download command accepts any user-supplied URL and fetches it without restricting the destination to Pixabay domains or validating scheme/host. In an agent skill intended as a Pixabay asset helper, this broad network/file-write primitive can be repurposed to access internal services or retrieve arbitrary remote content, increasing SSRF and unintended file download risk if exposed to untrusted input.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/freesound.ts:34

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/pexels.ts:33

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/pixabay.ts:34