Back to skill

Security audit

Md2docx

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed Markdown-to-Word converter with Chinese document formatting, with limited local-file risks users should understand before use.

Install only if you want a Chinese-oriented Markdown-to-Word workflow. Avoid running it on Markdown files located in shared or untrusted writable directories, and review generated documents because the tool currently appends a date line automatically.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
tools/md2docx.py:188
Finding
Predictable Temporary File Allows File Overwrite and Deletion## Vulnerability Details **File Location**: `tools/md2docx.py`, lines 188–192 and 262–264 **Vulnerability Type**: Predictable and non-exclusive temporary-file handling **Risk Level**: Medium ### Vulnerable Code ```python date_line = f"\n\n---\n\n{datetime.now().strftime('%Y年%m月%d日')}" temp_input_file = input_file.with_suffix(input_file.suffix + '.temp.md') try: with open(temp_input_file, 'w', encoding='utf-8') as f: f.write(content + date_line) # The temporary file is subsequently supplied to Pandoc. # ... finally: # Clean up temporary file if temp_input_file.exists(): temp_input_file.unlink() ``` ### Technical Analysis The converter constructs a deterministic temporary path by appending `.temp.md` to the input filename. It then opens that path in write mode without exclusive creation or protection against symbolic links. If the generated path already contains a regular file, the converter truncates and overwrites it. On platforms where symbolic links are supported, an attacker able to modify the input directory can pre-create the predictable path as a symbolic link to another file writable by the converter process. Opening the link in write mode follows it and replaces the target's contents with the generated Markdown. The cleanup operation then removes the predictable directory entry. The existence check before `unlink()` also introduces a time-of-check/time-of-use window. An attacker with concurrent directory access may replace the path between the check and deletion, although deletion normally affects the directory entry rather than the target of a symbolic link. No shell-command injection was identified in the Pandoc invocation because `subprocess.run()` receives an argument list and does not enable a shell. ### Attack Path 1. The victim selects an input such as `/shared/report.md`. 2. The attacker predicts that the converter will use `/shared/report.md.temp.md`. 3. Before conversion, the attacker creates th ...[truncated 1341 chars]
Remediation
## Remediation Suggestions 1. Replace the deterministic filename with a securely and atomically created temporary file using `tempfile.NamedTemporaryFile(delete=False)` or `tempfile.mkstemp()`. 2. Prefer a private, controlled temporary directory rather than the input file's directory. 3. Close and flush the temporary file before invoking Pandoc, particularly for cross-platform compatibility. 4. Retain the exact uniquely generated path and remove only that path in the `finally` block. 5. Avoid separate existence checks before cleanup. Attempt deletion directly and handle `FileNotFoundError`. 6. If a temporary file must be created beside the input, use exclusive creation and platform-appropriate protections against symbolic-link traversal. 7. Add tests covering: - A pre-existing candidate temporary file. - A symbolic link at the candidate path on supported platforms. - Concurrent replacement or removal during cleanup. - Cleanup after Pandoc failure. A safer implementation pattern is: ```python import os import tempfile temp_path = None try: fd, temp_name = tempfile.mkstemp( suffix=".md", prefix=f".{input_file.stem}-", dir=None, text=True, ) temp_path = Path(temp_name) with os.fdopen(fd, "w", encoding="utf-8") as temp_file: temp_file.write(content + date_line) # Invoke Pandoc with temp_path. finally: if temp_path is not None: try: temp_path.unlink() except FileNotFoundError: pass ```
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (10)

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The natural-language positioning describes the skill as a "中文场景专家" with Chinese font optimization, which signals a language-specific constraint. In this file, there is no accompanying note that users may choose another language/locale or that the restriction is an explicit opt-in, so it can conflict with language/locale policy expectations.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The skill documentation is written entirely in Chinese and presents the tool as a Chinese-document specialist, but it does not offer an alternative language, opt-in, or state that the skill is intentionally limited to a Chinese-speaking audience. Under the policy rule, forcing a specific language or locale without user choice is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The markdown states that the skill will '自动设置中文字体(Microsoft YaHei/SimSun)', which imposes a specific locale/language formatting choice by default. The file does not indicate that users can opt out of this behavior or that the locale restriction is required for a region-specific use case.

Intent-Code Divergence

Medium
Confidence
94% confidence
Finding
The module docstring presents this skill as a Markdown-to-Word converter with formatting enhancements, implying content-preserving conversion. However, the implementation later reads the source Markdown and appends a date line before conversion, which changes the document's substantive content rather than just formatting it.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This Python file contains multiple natural-language strings shown to users in Chinese, starting with the first raised error message at L73 and continuing throughout the CLI output. Because the skill does not offer language selection or state that it is intentionally limited to a Chinese-speaking context, it appears to force a specific language without user opt-in.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd.extend(["--reference-doc", str(ref_path)])

        try:
            result = subprocess.run(
                cmd, 
                capture_output=True, 
                text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
"解决方法:\n"
                "1. Windows: winget install pandoc\n"
                "2. macOS: brew install pandoc\n"
                "3. Linux: sudo apt install pandoc\n"
                "详细说明:https://pandoc.org/installing.html"
            )
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
True if Pandoc is available, False otherwise
    """
    try:
        subprocess.run(
            ['pandoc', '--version'],
            capture_output=True,
            text=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The script description and style settings hard-code Chinese fonts (宋体, 黑体) and create a locale-specific template with no indication that this behavior is optional or limited to a region-specific use case. Under the natural-language policy rule, forcing a specific language/locale without opt-in or documented justification is a policy concern.

Natural-Language Policy Violations

Low
Confidence
87% confidence
Finding
This code file includes natural-language content entirely in Chinese for the sample markdown document. Under the stated policy, forcing a specific language without user opt-in can be a locale-policy issue, and there is no comment or documentation here indicating that the test is intentionally region-specific or that alternate locales are supported.

Static analysis

No suspicious patterns detected.