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## 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
## 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## 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
## 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
Content
- `SKILL.md` - 本文档
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Sudo/Root Execution

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

## 🚀 使用方法
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
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.

Vague Triggers

Medium
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.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# 安装 pandoc (推荐)
# Windows: 下载安装包
# macOS: brew install pandoc
# Linux: sudo apt-get install pandoc
```

## 📋 使用场景
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
# 安装 pandoc (推荐)
# Windows: 下载安装包
# macOS: brew install pandoc
# Linux: sudo apt-get install pandoc
```

## 📋 使用场景
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Vague Triggers

Medium
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.

Natural-Language Policy Violations

Medium
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.

Missing User Warnings

Medium
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.

Vague Triggers

Medium
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.

Natural-Language Policy Violations

Medium
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.

Context-Inappropriate Capability

Medium
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.

Natural-Language Policy Violations

Medium
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.

Natural-Language Policy Violations

Medium
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.

Natural-Language Policy Violations

Medium
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.

Intent-Code Divergence

Medium
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.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
str(docx_path),
            '--outdir', str(output_path.parent)
        ]
        subprocess.run(cmd, check=True, capture_output=True)
        
        if verbose:
            print_success(f"Converted: {output_path}")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Medium
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.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
# 检查必需依赖
    for package, module in required.items():
        try:
            __import__(module)
        except ImportError:
            missing.append(package)
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
# 检查必需依赖
    for package, module in required.items():
        try:
            __import__(module)
        except ImportError:
            missing.append(package)
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Missing User Warnings

Medium
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.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
for package in missing:
            try:
                print(f"[INFO] 正在安装 {package}...")
                subprocess.check_call(
                    [sys.executable, "-m", "pip", "install", package],
                    stdout=subprocess.DEVNULL,
                    stderr=subprocess.DEVNULL
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.

Intent-Code Divergence

Low
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.

Natural-Language Policy Violations

Low
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.

Natural-Language Policy Violations

Low
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.

Static analysis

No suspicious patterns detected.