Back to skill

Security audit

平台视频转md

Security checks for vulnerabilities and agentic risk

Overview

This downloader needs review because it can save login secrets in logs and recommends browser-session access without clear consent.

Avoid password arguments and links containing secrets until log redaction is fixed. Approve browser-cookie access explicitly and use a dedicated profile; protect cookie exports as sensitive credentials ([yt-dlp FAQ](https://github.com/yt-dlp/yt-dlp/wiki/FAQ#how-do-i-pass-cookies-to-yt-dlp)). Keep logs and receipts private. Use an isolated environment and --no-update to control dependency upgrades.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (17)

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The download functionality matches the declared workflow, and probing, authentication options, dependency updates, and receipts are supporting implementation details. However, the description explicitly excludes media-format transcoding, while the audio-extraction options can convert audio into a requested format when the downloaded codec is incompatible. This is a concrete contradiction. The absence of MarkItDown in this downloader chunk alone is not treated as a separate mismatch because transcription may be implemented in another workflow stage.

Content

No source excerpt is available for this finding.

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

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

md
ylist`。
- **文件名**:合集默认 `NN - 标题 [id].ext`(带两位序号便于排序),单视频默认 `标题 [id].ext`;要纯 ASCII 文件名加 `--restrict-filenames`。
- **清晰度**:默认上限 1080p,用 `--max-height 720` 降低;要精确控制用 `--format "bv*[height<=720]+ba/b"`。
- **需要登录的内容**:先让用户在浏览器登录该站点,再加 `--cookies-from-browser chrome:Default`(Edge 写 `edge`,Firefox 写 `firefox`);也可用 `--cookies <Netscape 格式 cookies.txt>`。
- **字幕**:站点有字幕时用 `--sub-langs zh-Hans,en`,自动生成字幕加 `--write-auto-subs`。字幕单独存成 srt/vtt,用来校对 ASR 把专有名词听错的地方。

各站点差异见 [references/sites.md](references/sites.md)。

## 阶段二:转写成 Markdown(MarkItDown)

`video_to_md.py` 自动发现 MarkItDown 技能的 `scripts/convert_batch.py`(用户技能目录 → 工作区技能目录 → 插件缓存目录�

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · references/sites.md (reported line 10)May include surrounding context.

md
�当天版本即可恢复。`fetch_videos.py` 已内置这个判断与自动升级重试。
- 链接常带 `?vd_source=...&spm_id_from=...` 等跟踪参数,直接传给 yt-dlp 无害;出错时可截到 `https://www.bilibili.com/video/BVxxxx/` 再试。
- 清晰度:正式番号 BV 支持到 1080P(需登录)/ 4K(需大会员)。未登录时通常只给 360P–720P,要高清就加 `--cookies-from-browser chrome:Default`。
- 番剧、影视等 `ep` / `ss` 类链接支持不完整,常需要 Cookie 且仍可能失败;此时如实告知用户。
- 弹幕:`--write-subs` 取到的是字幕不是弹幕;弹幕需另用 `--write-comments`(得到 xml,MarkItDown 不解析,仅供人工参考)。

## YouTube

- 播放列表 URL 带 `list=PLxxxx`,默认展开全部;单视频 URL 只下 1 个。
- 部分客户端会触发 “Sign in to confirm you’re not a bot” → 加 `--cookies-from-browser`。
- 年龄限制内容必须登录并传 Cookie。
- 高分辨率(4

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · references/troubleshooting.md (reported line 15)May include surrounding context.

md
HTTP 412 Precondition Failed

- 出现在 B 站,逐集全报。原因是 yt-dlp 过旧,不是 Cookie 问题。
- 处理:脚本会自动升级并重试一次;手动处理时 `python -m pip install -U yt-dlp`。
- 确认版本:`yt-dlp --version`(日期版本号)。超过 90 天即视为过期。

### 403 / “Sign in to confirm you’re not a bot”

- YouTube 的反爬限流。加 `--cookies-from-browser chrome:Default`(浏览器须已登录);仍失败就换时段或降清晰度。
- 同一主机短时间大量请求容易被限流,大批下载时加 `--limit-rate 2M` 并分批。

### 只下到 1 集

- 检查是否传了 `--no-playlist`。默认会展开合集。
- 链接本身若是单视频(不含分P),那 1 集就是正确结果,先用 `--probe` 确认条目数。

### 格式合并 / 抽音轨失败

- 报 “ffmpeg not found” 或 “Postprocessing: ffmpeg exited” → 传 `--ffmpeg-location <ffmpeg 所在目录>`(含 ffmpeg.exe 的目录,不是

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/_vtmd_common.py (reported line 51)May include surrounding context.

python
def child_env():
    env = os.environ.copy()
    env["PYTHONIOENCODING"] = "utf-8"
    return env

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · scripts/fetch_videos.py (reported line 51)May include surrounding context.

python
-f 表达式")
    parser.add_argument("--max-height", type=int, help="限制最高清晰度,如 720 或 1080")
    parser.add_argument("--merge-output-format", default="mp4")
    parser.add_argument("--sub-langs", help="同时下载字幕,如 zh-Hans,en(自动生成字幕需 --write-auto-subs)")
    parser.add_argument("--write-auto-subs", action="store_true")
    parser.add_argument("--cookies-from-browser", help="从浏览器读取 Cookie,如 chrome:Default")
    parser.add_argument("--cookies", help="Netscape 格式 Cookie 文件路径")
    parser.add_argument("--username")
    parser.add_argument("--password")
    parser.add_argument("--proxy")
    parser.add_argument("--limit-rate", help="限速,如 2M")
    parser.add_argument("--concurrent-fragments", type=int, default=4)
    parser.add_argument("--retries", default="10")
    parser.add_argument("--download-archive", help="记录已下载条目的归档文件,用于跳过重复")
    parser.add_argument("--restr

Skill declares no tool scope ('permissions' or 'allowed-tools') but code capabilities were detected: env, file_read, file_write, network, shell.

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Browser-cookie authentication is instructed without warning about access to sensitive session credentials.

Medium
Category
Output Handling
Confidence
90% confidence
Finding

The skill recommends accessing browser cookies, including the default Chrome profile, without explaining that cookies can contain reusable authenticated-session credentials or requiring informed approval for that access. Authentication is legitimate in this context, but broad profile access or exported cookie files can expose credentials beyond the user's intended download task if dependencies, logs, or local artifacts are compromised; no actual credential theft is demonstrated.

Content

No source excerpt is available for this finding.

Browser-cookie instructions omit a warning about accessing authenticated session credentials.

Medium
Category
Output Handling
Confidence
93% confidence
Finding

The guidance recommends reading browser cookies to improve download quality or satisfy login requirements without warning that these are sensitive authenticated-session credentials or requiring explicit permission. Authentication is legitimate in this downloader context, but an agent following these instructions could expose a user's browser sessions to the downloader without informed consent; the file does not demonstrate credential exfiltration.

Content

No source excerpt is available for this finding.

Browser-cookie troubleshooting instructions lack a warning about accessing and using sensitive session credentials.

Medium
Category
Output Handling
Confidence
90% confidence
Finding

The troubleshooting advice directs an agent to use the default Chrome profile's authenticated cookies without explaining that these are sensitive session credentials or requiring explicit permission before accessing them. Authenticated downloading is legitimate in this skill, and the later restriction to content the user may access is helpful, but permission to download content does not necessarily authorize accessing browser credentials; following this advice automatically could cross that boundary.

Content

No source excerpt is available for this finding.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · scripts/_vtmd_common.py (reported line 56)May include surrounding context.

python
return env


def run(cmd, timeout=None, cwd=None):
    """Run a command and return (returncode, stdout, stderr). Never raises."""
    try:
        proc = subprocess.run(

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/_vtmd_common.py (reported line 59)May include surrounding context.

python
def run(cmd, timeout=None, cwd=None):
    """Run a command and return (returncode, stdout, stderr). Never raises."""
    try:
        proc = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

The downloader exposes an environment-modifying dependency upgrade capability outside its stated download-and-transcribe scope.

Medium
Category
Excessive Agency
Confidence
88% confidence
Finding

YtDlpTool.update() executes an upgrade command configured as either pip install -U yt-dlp (L225, L265) or executable self-update (L226). Unlike locating and invoking an installed downloader, this capability installs externally obtained code and modifies the selected Python environment or downloader executable; dependency management is not declared in the manifest.

Content

No source excerpt is available for this finding.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · scripts/_vtmd_common.py (reported line 343)May include surrounding context.

python
path.parent.mkdir(parents=True, exist_ok=True)
    tmp = path.with_suffix(path.suffix + ".tmp")
    tmp.write_text(
        __import__("json").dumps(payload, ensure_ascii=False, indent=2),
        encoding="utf-8",
    )
    os.replace(tmp, path)

Audio-only downloads can transcode media despite the manifest explicitly excluding media-format transcoding.

Medium
Category
Excessive Agency
Confidence
98% confidence
Finding

The manifest explicitly states that the skill does not perform media-format transcoding. However, L122-L125 pass yt-dlp --extract-audio with a requested output format (defaulting to m4a at L045), while selecting bestaudio/best without requiring a compatible source codec. When the downloaded audio is incompatible with that format, yt-dlp invokes FFmpeg to transcode it rather than merely downloading or remuxing it.

Content

No source excerpt is available for this finding.

Authentication credentials are written to the download log without a warning.

Medium
Category
Output Handling
Confidence
99% confidence
Finding

The script logs the complete command, including --username and --password values and potentially credentials embedded in proxy or download URLs. This persists authentication secrets in the output directory, where sharing or downstream processing can expose them; failed-download receipts can also duplicate these secrets through logTail.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/fetch_videos.py (reported line 244)May include surrounding context.

python
start = time.time()
    try:
        with open(log_path, "a", encoding="utf-8", errors="replace") as fh:
            proc = subprocess.run(
                [*tool.base, *cmd],
                stdout=fh,
                stderr=subprocess.STDOUT,