Back to skill

Security audit

Douyin Video Analyzer

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent Douyin video-analysis purpose, but its implementation has review-worthy unsafe execution and network-scoping risks.

Review before installing. Only run this in an isolated workspace/container, avoid private videos unless you accept Zhipu AI processing, do not provide untrusted URLs or filenames, and require fixes for shell execution, URL allowlisting, sandboxing, installer pinning, dependency updates, and reliable temporary-file cleanup.

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

T09 · Insecure Skill Coding Practices

Error
Location
lib/frame-extractor.js:29
Finding
Shell Command Injection Through Untrusted Paths and URLs<![CDATA[ ## Vulnerability Details **File Location**: `lib/frame-extractor.js:29-31, 92-96`; `lib/audio-processor.js:14-19, 40-42, 58-60`; `lib/video-downloader.js:66-68` **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```js // lib/frame-extractor.js const { stdout } = await execAsync( `ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "${videoPath}"` ); const fps = 1 / actualInterval; const command = `ffmpeg -i "${videoPath}" -vf "fps=${fps},scale='min(1280,iw)':-1" -q:v 2 "${framePattern}" -y`; console.log(` 🔄 正在提取关键帧...`); await execAsync(command); ``` ```js // lib/audio-processor.js const finalAudioPath = `${audioPathRaw}.wav`; return new Promise((resolve, reject) => { const cmd = `ffmpeg -i "${videoPath}" -vn -acodec pcm_s16le -ac 1 -ar 16000 -y "${finalAudioPath}"`; exec(cmd, (error) => { if (error) reject(error); else resolve(finalAudioPath); }); }); const getDurationCmd = `ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "${audioPath}"`; const duration = await new Promise((resolve) => { exec(getDurationCmd, (err, stdout) => resolve(parseFloat(stdout) || 0)); }); const cutCmd = `ffmpeg -ss ${startTime} -t ${SEGMENT_DURATION} -i "${audioPath}" -acodec copy -y "${segmentPath}"`; exec(cutCmd, (err) => err ? reject(err) : resolve()); ``` ```js // lib/video-downloader.js const command = `yt-dlp -o "${outputPath}" --no-warnings "${videoUrl}" 2>&1`; const { stdout, stderr } = await execAsync(command, { timeout: 120000 }); ``` ### Technical Analysis The Skill constructs shell command strings by interpolating local file paths, generated output paths, and browser-derived media URLs, then invokes them through `child_process.exec`. This API executes commands through a system shell. Wrapping a value in double quotes does not make it safe for shell execution. An input containing an embedded quote can terminate the quoted argum ...[truncated 1498 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace every `exec`/promisified `exec` invocation with `execFile` or `spawn` and an argument array: ```js await execFileAsync('ffprobe', [ '-v', 'error', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', videoPath ]); ``` 2. Invoke FFmpeg and yt-dlp with `shell: false`; never concatenate paths or URLs into a command string. 3. Validate media URLs with the `URL` API and allow only expected protocols and hosts. 4. Generate output identifiers locally from a restricted character set rather than incorporating remote identifiers directly. 5. Add regression tests using filenames and URLs containing quotes, command substitutions, semicolons, newlines, and platform-specific shell metacharacters. 6. Run media-processing tools under a dedicated unprivileged account or container with restricted filesystem and network access. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
lib/url-resolver.js:39
Finding
Unrestricted URL Handling Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/analyze.js:36-39, 91-97`; `lib/playwright-scraper.js:66`; `lib/url-resolver.js:39-76`; `lib/video-downloader.js:141-146` **Vulnerability Type**: Server-side request forgery and unrestricted redirect handling **Risk Level**: Medium ### Vulnerable Code ```js // scripts/analyze.js else if (!arg.startsWith('--')) { if (arg.startsWith('http')) result.videoUrl = arg; else if (fs.existsSync(arg)) result.localFile = arg; } ``` ```js // lib/playwright-scraper.js await page.goto(videoUrl, { waitUntil: 'networkidle', timeout: 60000 }); ``` ```js // lib/url-resolver.js const protocol = url.startsWith('https') ? https : http; const parsedUrl = new URL(url); const options = { hostname: parsedUrl.hostname, port: parsedUrl.port || (parsedUrl.protocol === 'https:' ? 443 : 80), path: parsedUrl.pathname + parsedUrl.search, method: 'HEAD', headers: { 'User-Agent': getRandomUserAgent(), 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8' } }; const req = protocol.request(options, (res) => { const statusCode = res.statusCode; const location = res.headers.location; if (statusCode >= 300 && statusCode < 400 && location) { let redirectUrl = location; if (!location.startsWith('http')) { redirectUrl = `${parsedUrl.protocol}//${parsedUrl.hostname}${location}`; } followRedirect(redirectUrl, maxRedirects - 1) .then(resolve) .catch(reject); } ``` ```js // lib/video-downloader.js if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { console.log(` 🔄 跟随重定向...`); downloadDirect(res.headers.location, outputDir, videoId) .then(resolve) .catch(reject); return; } ``` ### Technical Analysis The Skill is declared as a Douyin analyzer, but the argument parser accepts any string beginning with `http`. The supplied address is opened by Playwright and proce ...[truncated 1596 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse input with `new URL()` and require `https:`. 2. Allowlist the exact Douyin hostnames needed by the workflow. Maintain a separate, narrowly scoped allowlist for verified media-CDN hosts. 3. Resolve hostnames before each connection and reject loopback, private, link-local, multicast, unspecified, and reserved IPv4/IPv6 ranges. 4. Repeat full protocol, hostname, port, DNS, and IP validation after every redirect. 5. Reject URLs containing embedded credentials and restrict destination ports to those required by the service. 6. Set strict redirect, response-size, and request-time limits. 7. Apply outbound firewall or container-network rules so the process cannot reach metadata endpoints or private networks. 8. Avoid returning raw internal response details in errors or generated reports. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
lib/playwright-scraper.js:12
Finding
Arbitrary Web Content Is Rendered With the Chromium Sandbox Disabled<![CDATA[ ## Vulnerability Details **File Location**: `lib/playwright-scraper.js:12-15` **Vulnerability Type**: Browser isolation disabled **Risk Level**: Medium ### Vulnerable Code ```js const browser = await chromium.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] }); ``` ### Technical Analysis The Skill explicitly disables both Chromium sandbox mechanisms. At the same time, its entry point permits arbitrary HTTP(S) input and passes that input to `page.goto`. Consequently, web content that may be controlled by an attacker is processed without Chromium's principal process-isolation boundary. Disabling the sandbox does not by itself prove that a browser exploit exists, but it materially increases the consequence of a renderer or browser vulnerability. The declared scraping function does not inherently require disabling sandboxing, so these flags exceed least-privilege requirements. ### Attack Path 1. An attacker persuades a user to analyze an attacker-controlled URL. 2. The argument parser accepts the URL and launches Chromium with sandboxing disabled. 3. Chromium renders the attacker's HTML, JavaScript, media, and related resources. 4. If the content exploits a vulnerability in the installed Chromium version, the absence of sandboxing reduces or removes a major barrier between the compromised renderer and the host. 5. The resulting code runs in the security context available to the browser process. ### Impact Assessment A successful browser exploit could access files, process resources, and network destinations available to the account running the Skill. This may expose downloaded media, temporary files, and environment credentials. The exact scope remains bounded by operating-system account permissions and any external container or mandatory-access controls. ]]>
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--no-sandbox` and `--disable-setuid-sandbox`. 2. Run Chromium as a dedicated, non-root user in an environment where its normal sandbox can initialize. 3. If platform constraints make browser sandboxing impossible, isolate the complete Skill in a disposable container or virtual machine with: - No host filesystem mounts beyond a dedicated temporary directory. - No unnecessary Linux capabilities. - A read-only root filesystem where practical. - Restricted outbound networking. - No access to unrelated environment secrets. 4. Enforce the Douyin and media-CDN hostname allowlists before navigation. 5. Keep Playwright and Chromium pinned and promptly updated with security releases. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:11
Finding
Mutable Playwright Installation Command Can Fetch and Execute Unpinned Code<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:11-18`; `package.json:30-36`; `_meta.json:12-18` **Vulnerability Type**: Unsafe dependency installation and excessive installer privileges **Risk Level**: Medium ### Vulnerable Code ```yaml install: [ { "id": "playwright-deps", "label": "安装 Playwright 依赖", "kind": "exec", "command": "npx playwright install --with-deps chromium", }, ] ``` The equivalent installation command is also declared in `package.json` and `_meta.json`: ```json { "id": "playwright-deps", "label": "安装 Playwright 依赖", "kind": "exec", "command": "npx playwright install --with-deps chromium" } ``` ### Technical Analysis The installation command invokes `npx playwright` without specifying an exact version. If a suitable local executable is not resolved, `npx` can retrieve and execute a package at installation time. The effective installer can therefore differ from the code and lockfile reviewed during the audit. The `--with-deps` option may also install operating-system packages, giving the installation phase a substantially broader system-modification scope than downloading a Chromium build alone. Although the project includes a lockfile with integrity hashes, this command does not explicitly bind itself to the lockfile-pinned `playwright-chromium` package. ### Attack Path 1. The Skill's automated installation process runs the declared command. 2. `npx` attempts to resolve the `playwright` executable. 3. If it is not resolved from the intended locked dependency, `npx` may retrieve a mutable package from the configured registry. 4. Retrieved package code executes during installation. 5. `--with-deps` may invoke system package-management operations with the installer's available privileges. 6. A compromised registry package, registry configuration, or future incompatible package release can execute code or modify the host. ### Impact Assessment Impact is determined by the privi ...[truncated 426 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Install JavaScript dependencies with `npm ci` so versions and integrity values come from the committed lockfile. 2. Invoke the verified local binary directly, for example: ```sh ./node_modules/.bin/playwright install chromium ``` 3. Ensure the invoked binary belongs to the exact lockfile-pinned dependency and keep `package.json` and `package-lock.json` versions synchronized. 4. Do not use `npx` fallback package downloads in automated Skill installation. 5. Provision operating-system browser dependencies through a trusted, versioned base image or separately reviewed package-management step. 6. Avoid `--with-deps` in the Skill installer unless the required system changes are explicitly enumerated and approved. 7. Run dependency installation without access to production credentials. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/analyze.js:130
Finding
Temporary Media Cleanup Is Incomplete and Skipped on Failure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/analyze.js:130-136`; `lib/frame-extractor.js:120-131`; `lib/audio-processor.js:64-70`; disclosure mismatch at `SKILL.md:51` **Vulnerability Type**: Sensitive temporary-file retention **Risk Level**: Low ### Vulnerable Code ```js // scripts/analyze.js console.log(finalReport); // 清理临时文件 frameExtractor.cleanupFrames(framesDir); if (fs.existsSync(actualAudioPath)) fs.unlinkSync(actualAudioPath); } catch (error) { utils.printError(error.message); } ``` ```js // lib/frame-extractor.js function cleanupFrames(framesDir) { try { if (fs.existsSync(framesDir)) { const files = fs.readdirSync(framesDir); for (const file of files) { if (file.startsWith('frame_') && file.endsWith('.png')) { fs.unlinkSync(path.join(framesDir, file)); } } console.log(` 🧹 已清理 ${files.length} 个临时帧文件`); } } catch (error) { console.error(' ⚠️ 清理帧文件失败:', error.message); } } ``` ```js // lib/audio-processor.js const text = await callTranscribeAPI(segmentPath, apiKey); results.push(text); // 清理临时段 if (fs.existsSync(segmentPath)) fs.unlinkSync(segmentPath); ``` The documentation states that all temporary media under `temp/` is automatically deleted after each analysis, but the implementation does not remove downloaded videos or run-scoped directories. ### Technical Analysis Cleanup is performed only after the complete analysis succeeds. If frame extraction, audio segmentation, network transcription, visual analysis, report generation, or deletion throws an exception, control transfers directly to `catch`, bypassing the cleanup statements. Audio segments are deleted only after their corresponding API request returns. A failure before that deletion can leave a segment behind. Downloaded remote videos are not deleted by the shown success-path cleanup, and the frame/audio/download directories are not recursively removed. This behavior contradicts the document ...[truncated 1116 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a unique, securely permissioned directory for each analysis run using `fs.mkdtemp`. 2. Track all artifacts created by the Skill, including downloads, extracted audio, segments, and frames. 3. Move cleanup into a `finally` block so it runs after both success and failure: ```js let runDir; try { runDir = fs.mkdtempSync(path.join(TEMP_DIR, 'run-')); // Process media inside runDir. } finally { if (runDir) fs.rmSync(runDir, { recursive: true, force: true }); } ``` 4. Delete each audio segment in its own `try/finally` block around the transcription request. 5. Use restrictive directory and file permissions appropriate to the platform. 6. Handle termination signals where practical and perform stale-run cleanup at startup. 7. Update `SKILL.md` so its privacy statement precisely describes what is deleted and when. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
Findings (46)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
声明描述的是一个面向抖音视频的“完整分析报告”,覆盖数据、结构、视觉、文案多个维度;但这段代码仅是“AI 视觉分析模块”,其提示词和输出字段都明确聚焦于视觉维度。代码通过读取关键帧图片并发送给智谱 API,返回 visualStyle、colorScheme、textFrequency、hooks、recommendations 等结果,没有看到对抖音平台数据指标、视频脚本/文案文本、完整内容结构分析等功能实现。因此,代码行为只覆盖声明中的一部分(视觉拆解),与“完整分析报告”的主目的存在实质性不符。外部网络调用属于实现视觉分析所需的支持细节,不是主要不匹配点。

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
声明描述的是一个完整的抖音视频分析与报告生成能力,涵盖数据、结构、视觉、文案等多个维度。但给出的代码片段只负责音频相关处理:从视频抽取音频、测时长、分段、调用第三方 ASR 服务转写文本,并清理临时文件。它没有体现视频视觉分析、结构拆解、数据分析、文案分析或最终报告生成等核心功能。此外,声明权限为空,但代码实际会访问本地文件系统、调用系统级 ffmpeg/ffprobe,并向外部服务发送音频内容进行转录,属于未在声明中体现的资源访问能力。因此该代码片段与声明用途存在明显不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
声明描述的是一个内容分析型技能,重点应是对抖音视频做深度拆解并输出分析报告;而该代码块的核心行为是启动无头浏览器访问抖音链接,监听网络请求中的 aweme/detail 接口,抓取视频描述、作者、点赞/评论统计,并解析最高码率播放地址或从 DOM 中提取 video src。代码没有实现报告生成,也没有进行视觉分析、结构分析、文案分析等“深度拆解”能力。相反,它包含了一个未在描述中明确体现的能力:解析视频下载地址。因此声明与实际行为存在明显不一致。

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
声明强调的是“深度拆解”和“自动生成完整分析报告”,包括数据、结构、视觉、文案等高层分析能力。但这段代码的实际功能仅是底层抓取/解析模块:通过 HTTPS 请求抖音页面,提取基础视频信息并格式化部分字段。它没有实现报告生成,也没有看到对视频结构、视觉元素或文案进行分析的逻辑。虽然抓取数据可作为分析报告的支撑步骤,但就该代码块本身而言,其主要行为是数据采集而非完整分析,因此描述与实际行为存在明显不一致。

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
声明描述的核心能力是“分析抖音视频内容并生成完整报告”,应涉及视频内容、结构、视觉或文案层面的分析逻辑。但提供的代码仅是底层 URL 解析模块,负责处理抖音链接、跟随跳转并提取视频标识符,没有任何视频下载、内容解析、数据分析或报告生成功能。虽然这类链接解析可能是上层分析流程的支持组件,但就该代码块本身而言,其实际行为与声明的主要用途存在明显差异;此外,代码还执行了外部网络访问,而声明权限为空,也反映出能力表述不一致。

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
声明的核心能力是“分析抖音视频并自动生成完整分析报告”,而该代码块的核心功能完全是“下载视频”。它会访问网络、伪装请求头、调用外部下载工具、写入本地文件,但没有任何与视频内容解析、结构化分析、数据提取、视觉分析或文案生成相关的实现。因此这不是单纯的辅助细节,而是与声明用途 materially different 的主要行为,属于明显不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
声明的核心目标与代码的主要用途总体相关,确实是在对抖音视频进行拆解并生成分析报告。但代码实际能力明显超出描述:一是支持本地视频文件输入,而不只是抖音视频;二是会通过 Playwright 和下载器解析并下载远程视频;三是会提取音频并调用 ASR 做语音转文字,这属于额外的媒体处理能力。尤其“音频提取与 ASR”在描述中的“数据、结构、视觉、文案”里没有被清楚声明,且“Declared permissions”为空,也未体现对下载、浏览器抓取、文件处理的资源访问。因此应判定为存在描述与行为不完全一致的情况。

Ae1

High
Category
analysis-evasion
Content
node scripts/analyze.js "https://v.douyin.com/xxxxxx/"
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Credential Access

High
Category
Privilege Escalation
Content
| Download failed | Retry 3 times, then fallback to Phase 1 only |
| Frame extraction failed | Continue with available frames |
| API rate limit | Exponential backoff, max 5 retries |
| API key invalid | Clear error message, suggest checking .env |

## File Structure
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Self-Modification

High
Category
Rogue Agent
Content
## 8. Documentation

- [x] 8.1 Update SKILL.md with Phase 2 features
- [x] 8.2 Add usage examples for local file analysis
- [x] 8.3 Add documentation for third-party download tools (snapany.com)
- [x] 8.4 Document yt-dlp integration and limitations
Confidence
85% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Known Vulnerable Dependency: axios==1.13.6 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
98% confidence
Finding
axios 1.13.6 is flagged with multiple advisories, including SSRF-related proxy bypass and prototype-pollution-adjacent issues. In a skill that likely fetches remote Douyin pages and media metadata, a vulnerable HTTP client increases the risk of server-side request forgery, credential leakage, redirect abuse, or request manipulation when processing attacker-controlled URLs or proxy settings.

Known Vulnerable Dependency: form-data==4.0.5 — 1 advisory(ies): CVE-2026-12143 (form-data: CRLF injection in form-data via unescaped multipart field names and f)

High
Category
Supply Chain
Confidence
91% confidence
Finding
form-data 4.0.5 is flagged for CRLF injection through unescaped multipart field names or filenames. If this skill uploads files or forwards multipart data derived from untrusted input, an attacker may be able to inject crafted headers or corrupt downstream HTTP request structure, potentially enabling request smuggling-like effects or security control bypasses.

Known Vulnerable Dependency: undici==7.24.0 — 12 advisory(ies): CVE-2026-6733 (undici vulnerable to HTTP response queue poisoning via keep-alive socket reuse); CVE-2026-13697 (undici vulnerable to cross-user information disclosure and parse-time crash via ); CVE-2026-16728 (undici vulnerable to downstream response desynchronization via retry interceptor) +9 more

High
Category
Supply Chain
Confidence
94% confidence
Finding
undici 7.24.0 is flagged with multiple HTTP parsing and connection-reuse issues, including response queue poisoning and information disclosure. In this skill, cheerio pulls in undici for network operations, so any remote fetches to attacker-influenced endpoints could expose the process to response desynchronization, cross-request data leakage, or denial of service.

Known Vulnerable Dependency: axios==1.13.6 — 16 advisory(ies): CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more

High
Category
Supply Chain
Confidence
97% confidence
Finding
The static analysis reports a known vulnerable resolved `axios` version with multiple advisories, including SSRF-related and request-handling issues. In this skill, which fetches remote content and processes external Douyin/TikTok resources, an exploitable HTTP client flaw is more dangerous because attacker-controlled URLs, redirects, or proxy handling could influence outbound requests and data exposure.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The PRD explicitly plans scraping Douyin pages, downloading video files to local temporary storage, extracting frames/audio, and sending derived content to external AI/ASR services, but it does not require user-facing warnings, consent, or clear data-handling disclosures. This creates privacy, compliance, and local system-impact risk because users may not realize third-party content is being fetched, stored, processed, and potentially transmitted off-box.

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill declares access to environment-based secrets (`ZHIPU_API_KEY`) and uses external binaries, but does not define an explicit tool/permission scope. This weakens reviewability and can allow broader-than-expected execution or secret access when the skill is installed in permissive runtimes.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
Using `npx playwright install --with-deps chromium` without a pinned version creates a supply-chain risk: the installed package and its transitive dependencies may change over time and could introduce malicious or vulnerable code. Because this runs during installation and may install system dependencies, compromise would have significant impact on the host environment.

Rp1

Medium
Category
MCP Rug Pull
Confidence
97% confidence
Finding
The install step invokes `npx playwright` without pinning an exact package version, which allows whatever version resolves at execution time to be downloaded and executed. Because this is an install-time command that may fetch code from the public registry and runs with local user privileges, a compromised upstream package, dependency confusion scenario, or malicious newly-published version could lead to arbitrary code execution on the host.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The code converts local video frames to base64 and sends them to the external Zhipu API for analysis, but this file contains no explicit consent check, warning, redaction step, or privacy gate before transmission. Because video frames may contain faces, private locations, screens, or other sensitive data, silent third-party transfer creates a real privacy and data-handling risk, especially in a video-analysis skill where users may reasonably not expect external upload at frame level.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This code uploads audio data to a remote HTTPS endpoint and includes an Authorization bearer token, which affects user privacy and credential handling. While there are progress logs for segmentation, there is no confirmation prompt, warning log, or explanatory comment disclosing that audio content is transmitted to an external service.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The code builds an ffprobe shell command by interpolating a user-influenced videoPath into a string passed to child_process.exec. Although the path is wrapped in double quotes, shell metacharacters such as embedded quotes or command substitutions can still break out of quoting and lead to command injection, causing arbitrary command execution under the agent's privileges.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
Frame extraction invokes ffmpeg through exec using user-influenced videoPath and outputDir-derived paths, then creates and deletes files on disk. In this skill context, processing external video files is expected, which increases exposure to attacker-controlled paths; a crafted path can trigger shell injection, while unsafe output locations can lead to unintended file overwrite or deletion in accessible directories.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The skill’s stated purpose is to analyze Douyin videos and generate reports, but this code actively intercepts Douyin API responses and extracts a direct playable/download URL. That creates a capability to retrieve media content beyond metadata analysis, increasing the risk of unauthorized downloading or copyright/policy violations. In the context of an agent skill, this hidden expansion of scope is dangerous because downstream components may use the returned URL to save or redistribute content.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
This section explicitly falls back to DOM extraction of the video source when network interception fails, preserving a media-download capability that is not necessary for producing an analysis report. The dual extraction paths make the capability more robust and therefore more likely to be misused for content acquisition rather than analysis, especially in an automated skill context.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The request header hard-codes `Accept-Language` to prefer `zh-CN`, which imposes a specific locale behavior in the skill. The file does not offer any user opt-in or configuration for language selection, and no region-specific justification is documented here.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
lib/audio-processor.js:18