Back to skill

Security audit

Video App

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local video-generation skill, but its web server exposes risky unauthenticated media processing and avoidable security flaws that users should review before installing.

Install only in a trusted local environment, not on an exposed VPS, until the app adds authentication, upload limits, rate limiting, job timeouts, safe output cleanup, UUID validation on downloads, DOM-safe rendering, and patched/pinned dependencies. Treat submitted audio, images, and prompts as sensitive content handled by the local Node service and retained as generated MP4 outputs.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
index.js:97
Finding

Path Traversal in the Video Download Endpoint

Content
View full analysis
{ const filePath = path.join(__dirname, 'outputs', `${req.params.id}.mp4`); if (fs.existsSync(filePath)) { res.download(filePath); } else { res.status(404).send('Video not found'); } }); ``` ### Technical Analysis The `id` route parameter is inserted directly into a local filesystem path. The application does not verify that the value is a UUID, reject path separators, or confirm that the resolved path remains inside the intended `outputs` directory. Because route parameters are URL-decoded, a value containing encoded traversal sequences and path separators may cause `path.join()` to resolve a path outside `outputs`. The application then checks the attacker-selected path with `fs.existsSync()` and returns it with `res.download()`. The route always appends `.mp4`, so exploitation is limited to accessible files whose resulting path ends with that extension. This restriction reduces scope but does not prevent unauthorized access to media or other files using that extension. ### Attack Path 1. The attacker identifies the unauthenticated `/download/:id.mp4` endpoint. 2. The attacker supplies encoded `..` segments and path separators as the `id` parameter. 3. Express decodes the route parameter. 4. `path.join(__dirname, 'outputs', ...)` normalizes the traversal sequences and may produce a path outside the `outputs` directory. 5. If the resulting `.mp4` file exists and is readable by the Node.js process, `res.download()` returns it to the attacker. ### Impact Assessment A remote unauthenticated attacker may download files outside the intended output directory when: - The target path resolves to an existing file ending in `.mp4`. - The Node.js process has permission to read the target file. The vulnerability vi ...[truncated 225 chars]
Remediation
View remediation
{ if (!UUID_RE.test(req.params.id)) { return res.status(400).send('Invalid video identifier'); } const outputRoot = path.resolve(__dirname, 'outputs'); const filePath = path.resolve(outputRoot, `${req.params.id}.mp4`); if (!filePath.startsWith(`${outputRoot}${path.sep}`)) { return res.status(400).send('Invalid video identifier'); } res.download(filePath, (error) => { if (error && !res.headersSent) { res.status(error.statusCode === 404 ? 404 : 500).send('Unable to download video'); } }); }); ``` 2. Store generated IDs and corresponding server-controlled paths in a database or lookup table rather than deriving arbitrary paths from request parameters. 3. Apply authorization checks so that only the owner of a generated video can download it. 4. Run the service under a dedicated account with read access limited to application-owned directories. 5. Add automated tests using encoded traversal sequences, mixed separators, malformed UUIDs, and nonexistent identifiers. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
public/index.html:49
Finding

DOM-Based Cross-Site Scripting Through Untrusted Model and Error Output

Content
View full analysis
Scenes Description:
text
${data.scenes}

Video:

Download MP4 `; } else { resultDiv.innerHTML = `

Error: ${data.error}

`; } ``` ### Technical Analysis The application inserts several response fields directly into `innerHTML`: - `data.scenes` - `data.videoUrl` - `data.downloadUrl` - `data.error` The most important source is `data.scenes`, which originates from an Ollama response generated using an attacker-controlled prompt. Although the server asks the model to return only a Markdown list, this is a behavioral instruction rather than an output-security boundary. Prompt injection or unpredictable model output can cause HTML to be returned. Placing model-generated HTML into `innerHTML` allows the browser to parse it as markup. Active attributes such as event handlers can execute JavaScript. The error branch has the same unsafe rendering pattern, and server-side exception messages are returned by `index.js`. The video and download URLs are currently generated by the server rather than directly supplied by users, but they should still be assigned through validated DOM properties instead of HTML-string interpolation. ### Attack Path 1. An attacker supplies a prompt crafted to make the local language model return HTML rather than the requested Markdown list. 2. The server includes the model output in the `scenes` property of the JSON response. 3. The browser interpolates `data.scenes` into an HTML template. 4. The template is assigned to `resultDiv.innerHTML`. 5. The browser parses the model response as HTML. 6. If the response contains executable markup, such as an element with an activ ...[truncated 1107 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
index.js:14
Finding

Unauthenticated Media Processing Enables Resource Exhaustion and Persistent Disk Consumption

Content
View full analysis
{ try { const { prompt } = req.body; if (!prompt || !req.files.audio || !req.files.photo) { return res.status(400).json({ error: 'Missing audio, photo, or prompt' }); } const audioPath = req.files.audio[0].path; const photoPath = req.files.photo[0].path; const id = uuidv4(); const outputPath = path.join('outputs', `${id}.mp4`); // Generate scenes description with Ollama const scenesPrompt = `Create a detailed scene-by-scene description for a short music video synced to a melody. The video shows morphing/zoom/pan effects on one photo with audio waveform visualization at the bottom. User description/theme: "${prompt}". Output ONLY a markdown numbered list of 5 scenes with approximate timings (e.g. 0-10s: ...). Keep it vivid and matching the theme.`; const response = await ollama.chat({ model: 'llama3.2:1b', messages: [ { role: 'system', content: 'You are a creative music video director. Generate engaging scene descriptions.' }, { role: 'user', content: scenesPrompt } ], }); const scenesDesc = response.message.content; // Generate video with FFmpeg const args = [ '-loop', '1', '-tune', 'stillimage', '-i', photoPath, '-i', audioPath, '-filter_complex', `[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2,zoompan=z='min(zoom+0.001,1.5)':d=250:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':fps=30[photo]; [1:a]showwaves=s=1280x120:mode=line:colors=00ff00:scale=log:draw=full[wave]; [photo][wave]overl ...[truncated 3713 chars]
Remediation
View remediation
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (17)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code spawns FFmpeg as a child process to transform uploaded media into a video. Without a manifest describing the skill as a media-generation or transcoding tool, subprocess execution is an unjustified high-impact capability because it materially expands what the skill can do on the host.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: multer==2.0.2 — 8 advisory(ies): CVE-2026-5038 (Multer vulnerable to Denial of Service via incomplete cleanup of aborted uploads); CVE-2026-82333 (multer vulnerable to Denial of Service via oversized array index in field names); CVE-2026-3520 (Multer Vulnerable to Denial of Service via Uncontrolled Recursion) +5 more

High
Category
Supply Chain
Confidence
96% confidence
Finding

The application directly depends on multer 2.0.2, and the listed advisories are multiple denial-of-service issues in multipart upload parsing and cleanup. Because this is a video app and multer is commonly used for user-uploaded files, the skill context makes these findings more dangerous: an unauthenticated or low-privilege attacker may be able to exhaust server resources by sending malformed or abusive upload requests.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: path-to-regexp==8.3.0 — 2 advisory(ies): CVE-2026-4923 (path-to-regexp vulnerable to Regular Expression Denial of Service via multiple w); CVE-2026-4926 (path-to-regexp vulnerable to Denial of Service via sequential optional groups)

High
Category
Supply Chain
Confidence
90% confidence
Finding

path-to-regexp 8.3.0 is reported with ReDoS/DoS issues, and it is used by the router/express stack to process route patterns. While exploitation depends on specific route definitions and attacker-controlled paths, routing sits on the request path for all traffic, so availability risk can be significant if a vulnerable pattern is present.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: multer==2.0.2 — 8 advisory(ies): CVE-2026-5038 (Multer vulnerable to Denial of Service via incomplete cleanup of aborted uploads); CVE-2026-82333 (multer vulnerable to Denial of Service via oversized array index in field names); CVE-2026-3520 (Multer Vulnerable to Denial of Service via Uncontrolled Recursion) +5 more

High
Category
Supply Chain
Confidence
98% confidence
Finding

The project depends on multer 2.0.2, which is flagged with multiple denial-of-service vulnerabilities. In a video application, multer is likely used to process uploads, making the context more dangerous because malformed or malicious upload requests could exhaust resources or crash the service remotely.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill description is broad and does not define clear activation boundaries, inputs, or safety constraints, which can cause the agent to invoke it in unintended contexts. Because this skill launches a local webapp workflow that processes user media and prompts and depends on external binaries, ambiguous scope increases the chance of unnecessary exposure of local resources or accidental handling of sensitive content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill accepts user audio, photos, and prompts and sends them to a local web service for processing, but it does not warn users that their media and text will be transmitted to and handled by that service. This lack of transparency can lead to inadvertent exposure of sensitive personal content and prevents informed consent about how data is processed, stored, or logged.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

No manifest is available, so the skill has no declared purpose or scope to justify auxiliary AI-driven scene generation. The code does more than simple media processing by sending user prompt content to an Ollama model to create creative video scenes, which is a distinct capability from file handling or transcoding.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

User-provided prompt text is sent to a local LLM process and uploaded media is passed into FFmpeg without any visible disclosure, consent, or retention policy. In this skill context, the data flow is functionally expected, but the absence of transparent user-facing notice and handling controls creates a real privacy and trust issue, especially if users assume uploads are not further processed or stored.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This HTML/JS file collects user-provided media and text, then submits them via a POST request to /generate. While the form implies upload, there is no explicit warning or disclosure about transmitting potentially sensitive user content to a server for processing.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: body-parser==2.2.2 — 1 advisory(ies): CVE-2026-12590 (body-parser vulnerable to denial of service when invalid limit value silently di)

Low
Category
Supply Chain
Confidence
81% confidence
Finding

The lockfile pins body-parser 2.2.2, and the static finding cites a denial-of-service issue related to invalid limit handling. In a dependency lockfile, this is a real supply-chain exposure if the affected code path is reachable, though the impact is limited to availability and there is no evidence in this file alone of direct exploitation.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: qs==6.15.0 — 3 advisory(ies): CVE-2026-82417 (qs: Denial of Service via Attacker Controlled isBuffer); CVE-2026-8723 (qs has a remotely triggerable DoS: qs.stringify crashes with TypeError on null/u); CVE-2026-82562 (qs array-limit bypass via bracket-key comma parsing)

Low
Category
Supply Chain
Confidence
78% confidence
Finding

qs 6.15.0 has reported denial-of-service and parser edge-case issues, and it is commonly used to parse attacker-controlled query strings or form bodies. This is a real dependency risk, but in this file alone there is no evidence of especially dangerous usage, so the likely impact is limited to availability degradation rather than code execution or data compromise.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: uuid==13.0.0 — 1 advisory(ies): CVE-2026-41907 (uuid: Missing buffer bounds check in v3/v5/v6 when buf is provided)

Low
Category
Supply Chain
Confidence
66% confidence
Finding

uuid 13.0.0 is flagged for a missing bounds check in certain version generators when a caller supplies a buffer. This is likely a real library flaw, but exploitability depends on the application invoking the affected v3/v5/v6 APIs with attacker-influenced buffer arguments; the lockfile alone does not show such usage, so practical risk appears low.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency uses a caret version range, which allows future semver-compatible releases to be installed automatically. This increases supply-chain risk because a newly published compromised or breaking package version could be pulled in without explicit review.

Content

Scanner excerpt · package.json (reported line 13)May include surrounding context.

json
"author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^5.2.1",
    "multer": "^2.0.2",
    "ollama": "^0.6.3",
    "uuid": "^13.0.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The multer dependency is specified with a caret range, allowing automatic installation of later releases without explicit approval. In this case the package is also flagged as having known advisories, so leaving it unpinned worsens supply-chain and operational risk by making dependency state less predictable while already relying on a problematic package line.

Content

Scanner excerpt · package.json (reported line 14)May include surrounding context.

json
"license": "ISC",
  "dependencies": {
    "express": "^5.2.1",
    "multer": "^2.0.2",
    "ollama": "^0.6.3",
    "uuid": "^13.0.0"
  }

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Using a caret for ollama permits silent adoption of newer compatible releases during install. That weakens build reproducibility and can expose the application to accidental or malicious upstream changes in the dependency supply chain.

Content

Scanner excerpt · package.json (reported line 15)May include surrounding context.

json
"dependencies": {
    "express": "^5.2.1",
    "multer": "^2.0.2",
    "ollama": "^0.6.3",
    "uuid": "^13.0.0"
  }
}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The uuid package is not pinned to an exact version, so installs may resolve to different patch/minor releases over time. That creates reproducibility and supply-chain integrity issues, and is more concerning here because this package line is also associated with a known advisory.

Content

Scanner excerpt · package.json (reported line 16)May include surrounding context.

json
"express": "^5.2.1",
    "multer": "^2.0.2",
    "ollama": "^0.6.3",
    "uuid": "^13.0.0"
  }
}

Known Vulnerable Dependency: uuid==13.0.0 — 1 advisory(ies): CVE-2026-41907 (uuid: Missing buffer bounds check in v3/v5/v6 when buf is provided)

Low
Category
Supply Chain
Confidence
81% confidence
Finding

The dependency uuid 13.0.0 is associated with an advisory involving missing buffer bounds checks when specific API variants are used with a provided buffer. This is a real issue, but its practical impact depends on whether the application uses the affected v3/v5/v6 code paths with attacker-influenced buffer arguments; based on package.json alone, exposure is limited but still present.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
index.js:69