Back to skill

Security audit

format-flow

Security checks for vulnerabilities and agentic risk

Overview

This document-conversion skill is mostly purpose-aligned, but it automatically installs unpinned Python packages at runtime and can fetch arbitrary URLs without network safeguards.

Install only if you are comfortable with a converter that may modify the active Python environment by installing packages and may make outbound web requests when web conversion is used. Prefer reviewing and installing dependencies in an isolated virtual environment first, and avoid converting attacker-supplied URLs or broad recursive folders without checking the scope.

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)

T08 · Insecure Dependencies

Warning
Location
scripts/utils/dependencies.py:13
Finding

Automatic Installation of Unpinned Python Dependencies at CLI Startup

Content
View full analysis

Vulnerability Details

File Location: scripts/convert.py:17-29; scripts/utils/dependencies.py:13-68
Vulnerability Type: Automatic installation of unpinned third-party packages
Risk Level: Medium

Vulnerable Code

python
# scripts/convert.py:17-29
# 检查并安装依赖
from utils import (
    check_and_install_dependencies, 
    get_file_list, 
    print_info, 
    print_error,
    print_feature_status
)

success, missing = check_and_install_dependencies()
if not success:
    print_error(f"Failed to install dependencies: {', '.join(missing)}")
    sys.exit(1)
python
# scripts/utils/dependencies.py:13-68
def check_and_install_dependencies() -> Tuple[bool, List[str]]:
    """
    检查并自动安装缺失的依赖
    
    Returns:
        (是否全部安装成功, 缺失的依赖列表)
    """
    # 核心依赖(必需)
    required = {
        'python-docx': 'docx',           # Word 文档处理
        'pdfplumber': 'pdfplumber',      # PDF 文本提取
        'Pillow': 'PIL',                 # 图片处理
        'tqdm': 'tqdm',                  # 进度条
        'requests': 'requests',          # HTTP 请求(网页抓取)
        'beautifulsoup4': 'bs4',          # HTML 解析
        'openpyxl': 'openpyxl',          # Excel 处理
    }
    
    # 可选依赖(按功能分组)
    optional = {
        # 文档转换
        'pypandoc': 'pypandoc',          # Markdown → Word(高质量)
        'docx2pdf': 'docx2pdf',          # Word → PDF(Windows + MS Word)
        
        # 数据处理
        'pandas': 'pandas',              # Excel 高级处理
        
        # 图片处理
        'imageio': 'imageio',            # 图片 IO
    }
    
    missing = []
    installed = []
    
    # 检查必需依赖
    for package, module in required.items():
        try:
            __import__(module)
        except ImportError:
            missing.append(package)
    
    # 自动安装缺失的必需依赖
    if missing:
        print(f"[INFO] 检测到缺失依赖: {', '.join(missing)}")
        for package in missing:
  
...[truncated 2858 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove automatic package installation from module imports and normal CLI execution.
  2. Declare dependencies in pyproject.toml, a locked requirements file, or another standard package manifest.
  3. Pin reviewed package versions and use cryptographic hashes, such as pip's --require-hashes mode.
  4. Require users to perform an explicit installation step before invoking the converter.
  5. Install dependencies in a dedicated virtual environment or isolated container instead of modifying the active interpreter.
  6. Preserve pip output and installation errors so users can verify package sources and artifacts.
  7. Configure a trusted package index explicitly in controlled deployments.
  8. If automatic setup is essential, require explicit user confirmation and expose it as a separate command such as convert.py setup; do not run it for --help, --status, or conversion commands.
  9. Run dependency auditing and vulnerability scanning against the locked dependency set as part of release validation.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/converters/web_to_markdown.py:214
Finding

Unrestricted URL Fetching Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/convert.py:289-305; scripts/converters/web_to_markdown.py:214-240
Vulnerability Type: Server-Side Request Forgery through an unvalidated user-supplied URL
Risk Level: Medium

Vulnerable Code

python
# scripts/convert.py:289-305
elif args.command == 'web2md':
    # 判断是 URL 还是本地文件
    if input_path.suffix.lower() in ['.html', '.htm']:
        # 本地 HTML 文件
        convert_html_file_to_markdown(
            input_path,
            output_path=Path(args.output) if args.output else None,
            verbose=verbose
        )
    else:
        # URL
        convert_url_to_markdown(
            args.input,  # 保持原样(可能是 URL 字符串)
            output_path=Path(args.output) if args.output else None,
            include_metadata=not args.no_metadata,
            clean_content=not args.no_clean,
            verbose=verbose
        )
python
# scripts/converters/web_to_markdown.py:214-240
def convert_url_to_markdown(url: str, output_path: Optional[Path] = None,
                             include_metadata: bool = True,
                             clean_content: bool = True,
                             verbose: bool = True) -> bool:
    """
    将网页 URL 转换为 Markdown
    
    Args:
        url: 网页 URL
        output_path: 输出 Markdown 路径(可选)
        include_metadata: 是否包含元数据
        clean_content: 是否清理不必要的内容
        verbose: 是否显示详细信息
    
    Returns:
        是否转换成功
    """
    try:
        if verbose:
            print_info(f"Fetching: {url}")
        
        # 获取网页内容
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        }
        response = requests.get(url, headers=headers, timeout=30)
        response.raise_for_status()

Technical Analysis

The web2md command passes a user-controlled string directly to `requests.ge ...[truncated 2552 chars]

Remediation
View remediation

Remediation Suggestions

  1. Accept only explicitly supported schemes, preferably https and, where required, http.
  2. Reject URLs containing embedded credentials, ambiguous host syntax, or unsupported ports.
  3. Resolve the destination hostname before connecting and reject every address in loopback, private, link-local, multicast, unspecified, and reserved ranges for both IPv4 and IPv6.
  4. Explicitly block cloud metadata destinations and equivalent provider-specific hostnames.
  5. Disable automatic redirects or validate the scheme and resolved address of every redirect target before following it.
  6. Protect against DNS rebinding by connecting to the validated address and ensuring the connection cannot be transparently resolved to a different destination.
  7. Consider a domain allowlist for automated Agent deployments.
  8. Run the web converter in a sandbox that has no route to internal services or metadata endpoints.
  9. Enforce maximum response sizes, streaming download limits, permitted content types, and stricter connection/read timeouts.
  10. Log the final destination and redirect chain for security review without exposing credentials that may appear in URLs.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (31)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `SKILL.md` - 本文档

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 41)May include surrounding context.

md
对于 **Markdown 转 Word** 功能,需要安装 pandoc:
- **Windows**: 下载 https://pandoc.org/installing.html
- **macOS**: `brew install pandoc`
- **Linux**: `sudo apt-get install pandoc`

## 🚀 使用方法

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README does not clearly warn that conversions create output files, extracted-image folders, and potentially many files during batch or recursive runs. In an agent setting, this can lead to unintended filesystem modifications, data sprawl, overwrites, or leakage of extracted content into project directories without the user realizing it.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README says ordinary natural-language requests will automatically trigger the skill, but it does not define activation boundaries or require confirmation for file-writing operations. In an agent environment, broad trigger phrasing can cause unintended execution on user documents, including accidental batch conversions and processing of sensitive files.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 189)May include surrounding context.

安装 pandoc (推荐)

Windows: 下载安装包

macOS: brew install pandoc

Linux: sudo apt-get install pandoc

text

## 📋 使用场景

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

安装 pandoc (推荐)

Windows: 下载安装包

macOS: brew install pandoc

Linux: sudo apt-get install pandoc

text

## 📋 使用场景

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The top-level description includes very broad trigger terms such as "convert" and "extract text," which can cause the skill to activate for many unrelated requests. Overbroad routing increases the chance that the agent invokes file-processing or network-capable functionality without clear user intent, leading to unnecessary access to user content or unintended remote fetches.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Although some trigger keywords are bilingual, the operational instructions, headings, guidance, and examples are written in Chinese only. That effectively forces a specific language for users without an explicit opt-in or a documented reason for a Chinese-only locale.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill advertises web page conversion but does not clearly warn that converting a URL may initiate outbound network requests and disclose metadata such as IP, headers, and timing to third-party sites. Users may unknowingly trigger remote access when they expect only local document processing, creating a privacy and trust risk.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The web-processing triggers include vague phrases like "抓取网页" and "保存网页," which are not specific to Markdown conversion and may match broad browsing or retrieval requests. In this skill, that ambiguity is more dangerous because the feature can fetch remote URLs, potentially causing unintended network requests and exposure of request metadata.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code file contains natural-language descriptions and comments that force a specific language context for users and maintainers, including the module docstring and command-section labels. Under the policy, language-specific behavior should either offer user choice or clearly justify the locale restriction, which is not present here.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script performs dependency installation automatically at import/startup via check_and_install_dependencies(), which gives the skill package-management and network-fetch capability beyond simple file conversion. In an agent or semi-trusted execution environment, this can lead to unreviewed code being downloaded and executed, supply-chain compromise, unexpected privilege use, or environment mutation without explicit operator approval.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This Python file contains user-facing natural-language documentation exclusively in Chinese, beginning with the module description. Under the policy rules, forcing a specific language without user opt-in or documented justification is a locale-policy violation, and no language choice or regional rationale is present here.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code file contains natural-language descriptions and output strings that assume a Chinese-speaking user, beginning with the module docstring. The policy for this audit flags language/locale constraints when they are forced without user opt-in or clear justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code embeds its primary user-facing description and documentation in Chinese only, which can constitute a language/locale policy violation when no user opt-in or alternative language choice is provided. The file does not indicate that the language restriction is optional or justified by a region-specific purpose.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The docstring for convert_word_to_pdf describes a straightforward Word-to-PDF conversion routine, but the actual implementation includes invoking subprocess.run with soffice. Launching an external process is a materially different execution model and contradicts the implied in-process conversion behavior in the documentation.

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/converters/word_to_pdf.py (reported line 67)May include surrounding context.

python
str(docx_path),
            '--outdir', str(output_path.parent)
        ]
        subprocess.run(cmd, check=True, capture_output=True)
        
        if verbose:
            print_success(f"Converted: {output_path}")

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file's docstrings and all user-facing print messages are written only in Chinese, which imposes a specific language on users without any opt-in or explanation of a region-specific requirement. Under the stated policy, forcing a language/locale without user choice is a natural-language policy concern.

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/utils/dependencies.py (reported line 50)May include surrounding context.

python
# 检查必需依赖
    for package, module in required.items():
        try:
            __import__(module)
        except ImportError:
            missing.append(package)

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/utils/dependencies.py (reported line 75)May include surrounding context.

python
# 检查必需依赖
    for package, module in required.items():
        try:
            __import__(module)
        except ImportError:
            missing.append(package)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Automatically installing missing packages without explicit user consent is dangerous because it causes unreviewed code from external repositories to be fetched and installed during normal execution. In an agent/skill context, this is more dangerous because the skill may run unattended, in privileged environments, or on hosts where outbound package installation violates policy and introduces supply-chain risk.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
88% confidence
Finding

The code automatically invokes pip to install packages at runtime, which executes network-based package retrieval and installation in the current environment. Even though the package names are hardcoded, this behavior expands the attack surface through dependency confusion, compromised package indexes, malicious mirrors, or unexpected execution of install-time code, especially if the script runs with elevated privileges or in sensitive environments.

Content

Scanner excerpt · scripts/utils/dependencies.py (reported line 60)May include surrounding context.

python
for package in missing:
            try:
                print(f"[INFO] 正在安装 {package}...")
                subprocess.check_call(
                    [sys.executable, "-m", "pip", "install", package],
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The documentation first states that PDF→Markdown only extracts text and does not support image extraction, then immediately recommends running Tesseract on a scanned PDF. That creates an intent-level inconsistency in the README: the feature is presented as text-only, but the documented usage path relies on OCR over image-based PDF content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This Python file contains natural-language content only in Chinese ("转换器模块"), which can indicate a fixed language choice without any user opt-in or justification. Under the language/locale policy rule, forcing a specific language without documented choice or scope can be a policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The top-level docstring is written only in Chinese ('Excel 表格转 JSON 工具', '支持多种 JSON 结构输出'), which imposes a specific language in the skill's natural-language interface. The file does not indicate that the tool is region-specific or provide any opt-in or alternative language support.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.