Back to skill

Security audit

Generate DOCX

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate Chinese Word document formatting skill, but users should avoid its privileged install shortcuts and keep output paths controlled.

Install dependencies in a virtual environment or have an administrator provision Pandoc and fonts; do not let an agent run sudo or --break-system-packages automatically. Use explicit output paths in a private output directory, avoid shared writable directories, and do not pass untrusted raw Markdown/OpenXML into raw_markdown. Review generated legal, medical, financial, or official documents before relying on them.

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

Warning
Location
converter.py:461
Finding
Predictable Temporary File Allows Local File Overwrite and Deletion<![CDATA[ ## Vulnerability Details **File Location**: `converter.py`, lines 461–481 **Vulnerability Type**: Predictable and unsafe temporary-file handling **Risk Level**: Medium ### Vulnerable Code ```python tmp_md = str(output_path).replace(".docx", "_tmp.md") with open(tmp_md, "w", encoding="utf-8") as f: f.write(md) cmd = [ "pandoc", tmp_md, "--from", "markdown+pipe_tables+fenced_code_blocks+inline_notes+raw_attribute", "--to", "docx", f"--reference-doc={self.template}", "--output", output_path, ] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: raise RuntimeError(f"Pandoc 转换失败:\n{result.stderr}") try: os.unlink(tmp_md) except: pass ``` ### Technical Analysis The Markdown temporary path is generated deterministically by replacing `.docx` in the caller-supplied output path with `_tmp.md`. The file is then opened in write mode without exclusive creation, symlink checks, or verification that it is a newly created regular file. If a file already exists at the derived path, it is truncated and overwritten. If the path is a symbolic link, Python follows the link and overwrites its target using the privileges of the process. After a successful Pandoc conversion, the predictable path is unconditionally removed. This deletes a pre-existing regular file at that path or removes an attacker-created symlink. The cleanup also uses a broad exception handler, suppressing all failures and making unexpected cleanup behavior difficult to detect. Cleanup is not placed in a `finally` block, so the temporary file remains when Pandoc fails. ### Attack Path 1. The attacker determines or influences the output path passed to `DocxConverter.save()`. 2. The attacker derives the temporary path using the same replacement rule. For example, output `/shared/report.docx` produces `/shared/report_tmp.md`. 3. The attacker performs one of the following: - Places a valuable regular file at the derived tem ...[truncated 1272 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Create temporary files with Python's `tempfile` module using unpredictable names and atomic exclusive creation. - Prefer creating the temporary file in a private temporary directory. If it must be near the output, ensure the directory is trusted and not writable by untrusted users. - Store the exact generated path rather than deriving it through string replacement. - Perform cleanup in a `finally` block. - Catch only expected cleanup exceptions, such as `FileNotFoundError`, rather than suppressing every exception. - Validate that the output path has the expected `.docx` suffix and create its parent directory explicitly if required. - Where shared directories cannot be avoided, reject symlinks and verify file metadata before use. Example hardened implementation: ```python import os import tempfile from pathlib import Path output = Path(output_path) if output.suffix.lower() != ".docx": raise ValueError("The output path must use the .docx extension") output.parent.mkdir(parents=True, exist_ok=True) tmp_path = None try: with tempfile.NamedTemporaryFile( mode="w", encoding="utf-8", suffix=".md", prefix=".docx-converter-", dir=str(output.parent), delete=False, ) as tmp: tmp.write(md) tmp_path = tmp.name cmd = [ "pandoc", tmp_path, "--from", "markdown+pipe_tables+fenced_code_blocks+inline_notes+raw_attribute", "--to", "docx", f"--reference-doc={self.template}", "--output", str(output), ] result = subprocess.run(cmd, capture_output=True, text=True, check=False) if result.returncode != 0: raise RuntimeError(f"Pandoc conversion failed:\n{result.stderr}") finally: if tmp_path is not None: try: os.unlink(tmp_path) except FileNotFoundError: pass ``` ]]>

T08 · Insecure Dependencies

Note
Location
SKILL.md:67
Finding
Unpinned Dependency Installation Bypasses System Package Protections<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, line 67 **Vulnerability Type**: Unsafe dependency installation guidance **Risk Level**: Low ### Vulnerable Code ```bash python3 -c "import docx" || pip install python-docx --break-system-packages ``` ### Technical Analysis The documented initialization command installs `python-docx` without pinning a reviewed version or validating package hashes. The installed artifact can therefore vary over time based on the package index's current state and dependency resolution. The `--break-system-packages` option explicitly bypasses protections for externally managed Python environments. This can modify an operating-system-managed Python installation, introduce conflicts with distribution packages, and make rollback or reproducible deployment more difficult. The dependency name is legitimate and there is no evidence that the project intentionally installs a malicious or typosquatted package. The risk arises from floating dependency resolution and bypassing environment-isolation safeguards. ### Attack Path 1. `python-docx` is absent from the user's Python environment. 2. The user follows the installation instruction in `SKILL.md`. 3. Pip resolves the latest package and transitive dependencies available from its configured package index. 4. The package is installed directly into the externally managed system environment because `--break-system-packages` disables the normal safeguard. 5. A compromised package-index account, compromised mirror, maliciously configured index, or unsafe future dependency release could introduce unwanted code that executes during installation or later import. 6. Even without supply-chain compromise, incompatible dependency changes can alter or break system-managed Python applications. This path depends on the dependency being absent and the user executing the documented command. Supply-chain exploitation additionally requires compromise or malicious control of a configur ...[truncated 624 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Remove `--break-system-packages` from the installation instructions. - Require installation inside a dedicated virtual environment. - Pin `python-docx` and all transitive dependencies to reviewed versions. - Use a lock file or requirements file containing cryptographic hashes. - Install only from an explicitly trusted package index. - Add automated dependency scanning and scheduled version review. - Document separate environment setup commands instead of modifying system Python. Example safer setup: ```bash python3 -m venv .venv . .venv/bin/activate python -m pip install --upgrade pip python -m pip install --require-hashes -r requirements.txt ``` An accompanying `requirements.txt` should pin reviewed versions and hashes, for example: ```text python-docx==<reviewed-version> \ --hash=sha256:<reviewed-distribution-hash> ``` Hashes for all transitive dependencies must also be included when `--require-hashes` is used. ]]>
Vulnerability Patterns
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
该描述把技能定位为一个面向用户的“文档导出/排版生成器”,但提供的代码片段只是其构建阶段的模板生成工具。脚本主要作用是用 python-docx 预生成模板 reference.docx:设置页边距、字体映射、段落样式、标题样式、页脚页码和基础编号体系。这与“把用户内容按规范输出为 Word 文档”的最终行为存在明显差距。尤其是描述中强调的 Markdown 语义层、Pandoc 渲染引擎、最终 docx 导出、19 种文档类型、14 个模板等关键能力,在此代码中并未体现,且部分数量与实现不一致。虽然跨平台字体适配、首页页码控制、编号体系等确有部分支撑,但整体上代码行为只覆盖了声明能力中的一小部分底层模板准备工作,因此属于明显的描述—行为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
声明的核心能力是“生成/导出符合规范排版的 Word 文档”,即一个写出型、格式化型的文档生成器。实际代码却是一个 docx_reader,主要功能是输入现有 .docx,解析其中的段落、标题、列表、表格、代码块等结构,并输出结构化数据供后续处理,还附带 Markdown 调试输出和文档类型推断。这与声明的主用途明显不同:代码没有创建、修改、保存 .docx,也没有调用 Pandoc、模板系统或任何排版规范实现逻辑。虽然该读取器可能是更大系统中的辅助模块,但就该代码块本身而言,其行为与所述导出排版功能不符,且包含未声明的内容提取/分析能力。

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
该代码片段的主用途是“读取任意 .docx → 重新排版 → 输出新 .docx”。它依赖 docx_reader 提取原文档结构,再调用 DocxConverter 按识别出的块类型生成新文档。这与声明中的“将大模型生成或修改的内容导出为规范 Word 文档”并不完全一致:声明更像是一个从内容到 Word 的生成器,而代码是一个对既有 Word 文档进行解析和重排版的工具。虽然二者都与 Word 排版相关,且代码中也存在 Markdown 中间层,但核心输入形态、主要工作流和部分能力表述(如 19 种类型、Pandoc 引擎)与声明不完全吻合,因此应判定为存在描述与行为不匹配。

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill requires shell execution and file-writing behavior but does not declare any explicit tool scope or allowed-tools policy. That increases the chance an agent invokes broader-than-necessary capabilities, enabling unintended command execution or arbitrary file creation/overwrite during document generation.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
The description states that the skill formats output according to Chinese national and industry standards and examples throughout the file assume Chinese document conventions, fonts, and numbering. This imposes a specific language/locale behavior, but the skill does not clearly present this as an explicit opt-in constraint or offer a locale choice.

Vague Triggers

Medium
Confidence
95% confidence
Finding
Overly broad trigger phrases can cause the skill to activate for common document-related requests that did not clearly ask for file generation. In an agent setting, this can lead to unexpected shell use, document creation, or overwriting outputs when the user only wanted advice or plain-text formatting.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
pandoc --version   # 需要 Pandoc >= 2.0
# 安装:macOS: brew install pandoc | Ubuntu: sudo apt install pandoc
#        Windows: choco install pandoc 或 https://pandoc.org

python3 -c "import docx" || pip install python-docx --break-system-packages
Confidence
96% confidence
Finding
The skill documentation instructs use of privileged package-install commands such as 'sudo apt install pandoc' and also recommends 'pip install ... --break-system-packages'. In an agent-assisted workflow, normalizing privileged or system-modifying commands increases the risk of unnecessary elevation, host modification, and damage to the runtime environment if these instructions are followed automatically or uncritically.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill writes output documents but does not clearly warn users that it may create or overwrite files. In automated environments this can result in data loss, confusion about where artifacts are stored, or unauthorized modification of workspace files if paths are user-controlled or inferred implicitly.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
|------|---------|
| `pandoc: command not found` | 安装 Pandoc |
| 模板文件不存在 | `python3 build_templates.py` |
| 中文字体异常(Linux) | `sudo apt install fonts-noto-cjk` |
| 编号未从1重置 | 确保两个列表间有 `h1/h2/body` 调用 |
| 代码缩进丢失 | 确认 Pandoc >= 2.0;使用 `code_block()` |
| 四级标题不显示 | `GOV_DOC`/`LEGAL_DOC` 类型支持 h4 |
Confidence
93% confidence
Finding
Recommending 'sudo apt install fonts-noto-cjk' in troubleshooting encourages privileged system modification for a formatting issue. While less severe than arbitrary command execution, it still expands the blast radius of a document-formatting skill and can lead to unintended host changes in automated or semi-automated agent contexts.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This Python file contains natural-language instructions and output text entirely in Chinese, including the module docstring that explains how to run the script. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The module docstring is written as prescriptive Chinese-language documentation and includes locale-specific formatting conventions such as Chinese numbering and Chinese font rules, but does not indicate that users may choose another language or that the converter is limited to a China-specific regulatory context. This can amount to a language/locale policy violation under the requirement to avoid forcing a specific language without user opt-in.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The raw_markdown API allows arbitrary Markdown insertion even though the skill is supposed to be a constrained DOCX formatter. In this codebase, Markdown is rendered by Pandoc with raw OpenXML support enabled, and there is also a page_break method that injects raw OpenXML directly, so untrusted callers can potentially smuggle active content or unsafe document constructs into the generated .docx beyond intended formatting controls.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
f"--reference-doc={self.template}",
            "--output", output_path,
        ]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode != 0:
            raise RuntimeError(f"Pandoc 转换失败:\n{result.stderr}")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
The file’s top-level description states its behavior entirely in Chinese, including output expectations, and later docstrings and summary labels are also fixed to Chinese. This creates a locale policy concern because the skill appears to impose a specific language on users without offering any language selection or documenting a justified region-specific constraint.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The summary function returns user-facing text with fixed Chinese labels such as '标题' and '正文'. Because no option exists to choose another language or locale, this is a natural-language policy violation under the language/locale rule.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The module docstring, CLI help text, status messages, and usage instructions are entirely in Chinese, indicating the skill is designed to communicate in a specific language by default. There is no indication that users can choose another language or opt in to this locale constraint, which matches the policy's language/locale violation criterion.

Intent-Code Divergence

Low
Confidence
99% confidence
Finding
The top-level documentation states '输出:templates/ 目录下 9 个模板文件', but TEMPLATES contains 14 entries and the main routine iterates over all of them, printing the final count via len(TEMPLATES). This is an active documentation-to-code contradiction about what the script produces.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The script's user-facing print statements at runtime are Chinese-only, which forces a specific language for operational feedback. The file does not offer an alternative language or indicate that the tool is intentionally restricted to a Chinese-speaking environment.

Context-Inappropriate Capability

Low
Confidence
81% confidence
Finding
The skill's stated purpose is document formatting/export, but the implementation depends on launching the external `pandoc` binary via `subprocess.run()`. Spawning subprocesses is a broader execution capability than a pure formatter typically needs at the code boundary, and it increases operational risk if exposed in a wider agent runtime.

Static analysis

No suspicious patterns detected.