Back to skill

Security audit

在线视频转文字稿

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent for video transcript extraction, but its instructions expose users to review-worthy command-injection and supply-chain risks.

Review before installing. Use it only for public or non-sensitive video links, and prefer a revised version that passes URLs, titles, and transcript text as structured process arguments or stdin rather than interpolated shell text. Pin dependencies and add a lockfile before relying on it in a sensitive environment.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:55
Finding
Command Injection Through Untrusted URL, Video Metadata, and Subtitle Content<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:55-64`, `SKILL.md:108-126` **Vulnerability Type**: Command injection through unsafe shell-command construction **Risk Level**: High ### Vulnerable Code ```powershell # SKILL.md:55-64 # Try manual subs first, fall back to auto-generated yt-dlp --skip-download --write-subs --write-auto-subs --sub-langs "en,zh-Hans,zh-Hant,zh" --convert-subs srt -o "$tmp\sub" "<URL>" ``` ```powershell # SKILL.md:108-126 # Original node "~/.agents/skills/video-transcript/scripts/make_docx.js" "$tmp\transcript_original.docx" "<VideoTitle> - Original" "<plain_text>" # Chinese translation node "~/.agents/skills/video-transcript/scripts/make_docx.js" "$tmp\transcript_zh.docx" "<VideoTitle> - 中文译稿" "<chinese_text>" ``` The alternative workflow still interpolates an untrusted title: ```powershell $plain | Out-File -Encoding utf8 "$tmp\content.txt" Get-Content "$tmp\content.txt" -Raw | node "~/.agents/skills/video-transcript/scripts/make_docx.js" "$tmp\transcript_original.docx" "<title>" ``` ### Technical Analysis The documented workflow places user-controlled or remotely controlled values directly into PowerShell command text: - The video URL comes from the user. - The title may come from remote video metadata. - The original transcript can come from remotely hosted subtitles. - The translated transcript is derived from that untrusted subtitle content. Surrounding a substituted value with double quotes is not sufficient when the value itself can contain quotation marks, PowerShell statement separators, subexpressions, or other shell metacharacters. If the agent constructs a textual command by replacing placeholders such as `<URL>`, `<VideoTitle>`, or `<plain_text>`, a malicious value can terminate its quoted argument and introduce additional PowerShell syntax. The stdin-based variant avoids placing the transcript body in an argument, but it continues to place the video title directly into the command. It therefo ...[truncated 1349 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not generate shell command strings by interpolating URLs, titles, or transcript content. 2. Invoke child processes through an API that accepts an executable and a structured argument array, with shell processing disabled. For example, use Node.js `spawn` or `execFile` with `shell: false`. 3. Pass transcript content through stdin or a temporary file rather than through a command-line argument. 4. Pass the video title as a discrete process argument through the same structured API. 5. Use the `--` end-of-options separator before the URL where supported, preventing a URL beginning with `-` from being interpreted as an option. 6. If PowerShell must be used, retain values in variables and pass those variables as arguments without constructing and evaluating a new command string. Do not use `Invoke-Expression`. 7. Validate URLs against an explicit set of permitted schemes, such as `https`, and reject control characters, line breaks, and unexpected schemes. 8. Generate output filenames independently from remote metadata. If metadata is used in a filename, normalize it to a conservative allowlist and enforce a known output directory. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/package.json:13
Finding
Unpinned and Unlocked Third-Party Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:13-20`, `SKILL.md:36-44`, `scripts/package.json:13-15` **Vulnerability Type**: Mutable dependency resolution and supply-chain exposure **Risk Level**: Medium ### Vulnerable Code ```yaml # SKILL.md:13-20 dependencies: - name: yt-dlp install: "pip install yt-dlp # or: winget install yt-dlp" check: "yt-dlp --version" - name: node install: "https://nodejs.org" check: "node --version" - name: docx (npm, local) install: "cd ~/.agents/skills/video-transcript/scripts && npm install" check: "node -e \"require('./node_modules/docx')\"" ``` ```powershell # SKILL.md:36-44 $skillScripts = "$env:USERPROFILE\.agents\skills\video-transcript\scripts" if (-not (Test-Path "$skillScripts\node_modules\docx")) { Push-Location $skillScripts npm install Pop-Location } ``` ```json // scripts/package.json:13-15 "dependencies": { "docx": "^9.6.1" } ``` ### Technical Analysis The installation workflow resolves dependencies from public package repositories at setup time without a reproducible dependency lock: - `pip install yt-dlp` does not specify an exact version or artifact hash. - The `docx` dependency uses the mutable semver range `^9.6.1`. - The reviewed project contains no `package-lock.json` in the supplied directory structure. - The setup instructions use `npm install`, allowing dependency resolution to change across installations. As a result, the code installed and executed in a future environment is not fully determined by the audited project. A newly published compatible package or transitive dependency can be selected without further source review. Package installation may also execute package lifecycle scripts, while imported dependency code executes when `make_docx.js` loads `docx`. No evidence shows that the currently named packages are malicious. The vulnerability is the inability to reproduce and verify the dependency set, which creates an avoidable su ...[truncated 1055 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `docx` to a reviewed exact version rather than a caret range. 2. Generate and commit `package-lock.json`, including resolved transitive versions and integrity metadata. 3. Replace `npm install` with `npm ci` so installation fails if the manifest and lockfile differ. 4. Pin `yt-dlp` to a reviewed exact version. 5. Use Python hash verification, such as a requirements file containing exact versions and `--hash` entries, and install with `--require-hashes`. 6. Use trusted, explicitly configured package registries and secure transport. 7. Review dependency provenance, release signatures where available, lifecycle scripts, and transitive changes before updating lockfiles. 8. Run dependency installation and document generation with least privilege and, where practical, inside a restricted environment without unnecessary access to credentials or sensitive directories. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (6)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This is a clear description/behavior mismatch. The description promises a workflow that accepts video links and extracts spoken content/subtitles, but the code shown has no logic for URLs, downloading videos, calling yt-dlp, fetching subtitles, speech-to-text, or processing media in any way. Its sole behavior is converting existing plain text into a .docx file. While producing a .docx is consistent with part of the declared output format, the central advertised capability—getting transcript text from video sources—is absent.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared purpose describes an end-to-end video transcript extraction workflow from URLs, including support for multiple platforms and delivery as .docx documents. The actual code chunk does not access URLs, download videos or subtitles, invoke yt-dlp, or create Word documents. Its sole function is to parse an already-existing SRT subtitle file into plain text. This is materially narrower and different from the declared primary purpose, so it is a mismatch.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The trigger scope is broad enough that users pasting a video URL and asking generally for text content could invoke networked retrieval and local file-generation actions without clear confirmation. In this context, that increases the chance of unintended external requests, processing of sensitive/private links, or accidental execution of heavyweight toolchains.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill sends user-supplied video URLs to yt-dlp and the target platform, but the description does not clearly warn users that their link and retrieval metadata will be disclosed to external services. This is dangerous because users may provide private, unlisted, internal, or sensitive URLs assuming the action is local-only.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
Automatically translating all non-Chinese transcripts into Chinese without opt-in can expose content to additional model processing and produce outputs the user did not request. While not severe on its own, it can create unnecessary data handling and privacy risk, especially for sensitive or copyrighted material.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"license": "ISC",
  "type": "commonjs",
  "dependencies": {
    "docx": "^9.6.1"
  }
}
Confidence
93% confidence
Finding
The dependency version is specified with a caret range (^9.6.1), which permits automatic installation of newer compatible releases. This creates supply-chain risk because builds are not fully reproducible and a compromised or regressed upstream release could be pulled in without an intentional review.

Static analysis

No suspicious patterns detected.