Back to skill

Security audit

URL to Video Generator

Security checks for vulnerabilities and agentic risk

Overview

The skill is not overtly malicious, but it needs review because it fetches websites, downloads packages/media, and writes generated project files with weak scoping and unsafe input handling.

Install or run this only in a restricted workspace with minimal credentials and network access. Use only public, non-sensitive website URLs; validate brand names as simple slugs before running the scaffold script; review generated files before npm install/build; and prefer pinned dependencies, a lockfile, and local Remotion binaries instead of npx-fetched commands.

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

Error
Location
scripts/extract_colors.py:11
Finding

Unvalidated Website Fetch Enables Server-Side Request Forgery and Unbounded Response Consumption

Content
View full analysis
") sys.exit(1) url = sys.argv[1] if not url.startswith('http'): url = 'https://' + url print(f"Extracting colors from {url}...\n") colors, rgb_colors = extract_colors(url) ``` ### Technical Analysis The script accepts an arbitrary URL and passes it directly to `urllib.request.urlopen`. It does not strictly validate the URL scheme, resolve and inspect the destination address, reject private or reserved networks, or validate the destination again after an HTTP redirect. Consequently, an attacker who can control the script argument can cause requests to loopback addresses, link-local services, private network hosts, or other endpoints reachable from the execution environment. Public endpoints that redirect to internal addresses can also bypass checks because redirect targets are not inspected. The call to `response.read()` reads the complete response into memory. The 15-second timeout limits waiting time but does not impose a maximum response size. A remote server can therefore return an excessively large or continuously streamed response and cause significant memory consumption. ### Attack Path 1. An attacker supplies a URL such as an internal HTTP service, loopback endpoint, o ...[truncated 1256 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/init-project.sh:6
Finding

Unvalidated Brand Name Enables Directory Traversal and Generated-File Injection

Content
View full analysis
" echo "Example: ./init-project.sh futurai https://futurai.org" exit 1 fi PROJECT="remotion-${BRAND}-promo" echo "Creating project: $PROJECT" mkdir -p "$PROJECT"/{src,audio,out,stills} cd "$PROJECT" ``` ```bash cat > package.json << EOF { "name": "$PROJECT", "version": "1.0.0", "scripts": { "start": "remotion studio", "build": "remotion render src/index.tsx ${BRAND}-promo out/video.mp4", "stills": "remotion still src/index.tsx ${BRAND}-promo" }, "dependencies": { "@remotion/cli": "^4.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", "remotion": "^4.0.0" }, "devDependencies": { "@types/react": "^18.2.0", "typescript": "^5.0.0" } } EOF ``` ```bash cat > src/index.tsx << EOF import { registerRoot, Composition } from 'remotion'; import { ${BRAND^}Promo } from './${BRAND^}Promo'; registerRoot(() => ( )); EOF ``` ### Technical Analysis The `BRAND` parameter is accepted without character, length, path, or identifier validation. It is used in three different security-sensitive contexts: 1. **Filesystem path construction:** `PROJECT="remotion-${BRAND}-promo"` 2. **JSON generation:** values and npm script commands in `package.json` 3. **TypeScript generation:** imports, identifiers, and string literals in `src/index.tsx` Shell quoting around `"$PROJECT"` prevents ordinary shell word splitting, but it does not make a path containing `/` or `..` safe. A crafted brand can introduce path components that cause ...[truncated 2249 chars]
Remediation
View remediation
&2 exit 1 fi ``` 2. Reject `/`, `\`, `..`, control characters, whitespace, quotes, and shell/source-language metacharacters. 3. Resolve the final project path with `realpath` and verify that it remains under an explicitly selected base directory. 4. Refuse to overwrite an existing destination unless the operator explicitly requests it. 5. Generate `package.json` using a JSON-aware tool or serializer rather than an interpolated heredoc. 6. Derive a separate PascalCase TypeScript identifier from the validated slug and validate it against TypeScript identifier rules. 7. Pass dynamic values into source templates through a safe templating mechanism with context-specific escaping. 8. Avoid embedding user input directly into npm command strings. 9. Create files with restrictive permissions and use atomic, no-clobber writes where practical. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/init-project.sh:20
Finding

Mutable npm Dependency Versions Create a Supply-Chain Exposure

Content
View full analysis
package.json << EOF { "name": "$PROJECT", "version": "1.0.0", "scripts": { "start": "remotion studio", "build": "remotion render src/index.tsx ${BRAND}-promo out/video.mp4", "stills": "remotion still src/index.tsx ${BRAND}-promo" }, "dependencies": { "@remotion/cli": "^4.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", "remotion": "^4.0.0" }, "devDependencies": { "@types/react": "^18.2.0", "typescript": "^5.0.0" } } EOF ``` The corresponding instructions in `SKILL.md`, lines 39–45, also direct installation without a reviewed lockfile: ```bash mkdir -p remotion-{brand}-promo/{src,audio,out} cd remotion-{brand}-promo npm init -y npm install remotion @remotion/cli react react-dom npm install -D typescript @types/react ``` ### Technical Analysis The initializer uses caret version ranges, and the documentation installs packages without versions. Both approaches permit npm to resolve package releases that were not present when the skill was audited. No reviewed `package-lock.json` is included to provide an integrity and transitive-dependency baseline. As a result, two installations performed at different times may retrieve materially different code. npm packages and their transitive dependencies may execute lifecycle scripts during installation, so compromise of a permitted future release can affect the host before the project is built. No evidence was found that the named packages are currently malicious. The security issue is the unsafe, mutable dependency-resolution process and the resulting exposure to future package or registry compromise. ### Attack Path 1. A permitted package release or transitive dependency is compromised, or a vulnerable version is publis ...[truncated 1064 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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 (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description promises a broad website-to-promotional-video capability, but the actual code only performs color extraction from a webpage and outputs a suggested palette. While color extraction could be a supporting subcomponent for branding in video generation, this chunk by itself does not implement the primary declared behavior and lacks the major advertised capabilities such as content extraction for scenes, Remotion/React composition, narration, music, or rendering. Therefore the description does not accurately represent what this supplied code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description promises an end-to-end website-to-promotional-video workflow driven by a website URL, including scraping, content extraction, Remotion animation setup, TTS narration, free BGM, and rendering. The supplied code only initializes a project skeleton: it creates directories and config files, sets up package.json and a Remotion composition stub, writes placeholder narration text, and downloads a background music file. Although downloading free BGM and basic Remotion setup align partially with the description, the core advertised behavior—turning a website into a video—is absent. The provided URL parameter is not used for scraping or content generation at all. Therefore the description materially overstates the implemented functionality.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill clearly instructs use of shell and network operations (python3, curl, npm, npx remotion) but declares no permissions or allowed-tools scope. That creates an overbroad execution surface where an agent may invoke powerful capabilities without an explicit least-privilege contract, increasing the risk of unintended external access, downloads, and command execution.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The description states the output includes Chinese narration, imposing a specific language by default. The file does not present this as an opt-in choice or explain that the skill is limited to a Chinese-language context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill directs scraping and remote fetching of user-supplied websites without clearly warning that the URL and retrieved content will be transmitted to external services or remote hosts. This can expose sensitive internal URLs, private staging sites, or confidential content to third parties and can also trigger unwanted outbound requests from the agent environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The workflow instructs downloading packages and media from the internet (npm install, curl to Pixabay) without explicit warning or consent. This exposes the runtime to supply-chain, licensing, and privacy risks, especially if executed automatically in a privileged environment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The instructions require use of the TTS tool to generate Chinese narration, which is a natural-language locale constraint. No alternative language path or user preference check is provided.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

Using npx remotion without a pinned version allows whatever package version is current at execution time to be fetched and run. This creates a supply-chain risk: behavior can change unexpectedly, and a compromised or malicious upstream package version could execute arbitrary code in the agent environment.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

This npx remotion invocation is also unpinned, so it may download and execute an arbitrary current version from the registry. In an automated skill context, repeated dynamic package execution materially increases supply-chain exposure.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

The command at this line relies on npx remotion without version pinning, exposing the environment to uncontrolled upstream changes and potential arbitrary code execution from dependencies. Because the skill encourages users to run these commands directly, the risk is practical rather than theoretical.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

This screenshot-generation command again uses an unpinned npx remotion, which can fetch code at runtime. Any compromise or incompatible upstream change could affect the host, outputs, or subsequent automated steps.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

The skill repeats the same unpinned package execution pattern here, compounding supply-chain risk across multiple workflow steps. In agentic environments, such patterns are dangerous because the commands may run non-interactively with filesystem and network access.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
89% confidence
Finding

This final npx remotion occurrence shares the same vulnerability: dynamic execution of an unpinned remote package. Multiple occurrences indicate a systemic reproducibility and supply-chain security issue in the skill design.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The constraints section says 'Chinese Narration' is required for all segments, making the language requirement mandatory rather than optional. This forces a specific locale without user choice.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

extract_colors returns filtered, which is a plain dictionary built at L31-L39, but main() treats colors as if it were still a Counter by calling colors.most_common(10). This conflicts with the apparent intent of printing the top colors and indicates the code/documented behavior is out of sync with the implementation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The script automatically fetches an external MP3 via curl, which is a network operation that contacts a third-party host. Although it prints "Downloading free BGM...", that message does not clearly disclose the remote source or that data is being transmitted to an external service.

Content

No source excerpt is available for this finding.