Back to skill

Security audit

PDF带格式转换成Word

Security checks for vulnerabilities and agentic risk

Overview

This skill is a local PDF-to-Word converter with some quality and temporary-file caveats, but no evidence of hidden access, persistence, exfiltration, or malicious behavior.

Install only if you are comfortable running a local PDF converter that may not preserve formatting as precisely as advertised. Use it in a private working directory, especially for confidential PDFs, because extracted image files may briefly appear or remain there if errors occur. Review or fix the temporary-file handling and import issues before relying on it for sensitive or production use.

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
scripts/convert.py:117
Finding

Predictable Temporary Image Files Permit File Overwrite and Data Exposure

Content
View full analysis

Vulnerability Details

File Location: scripts/convert.py:117-119; incomplete cleanup at scripts/convert.py:276-282
Vulnerability Type: Predictable and unsafe temporary-file handling
Risk Level: Medium

Vulnerable Code

python
img_path = f"_temp_img_{page.number}_{img_index}.{image_ext}"
with open(img_path, "wb") as f:
    f.write(image_bytes)
content['images'].append({
    'path': img_path,
    'width': base_image["width"],
    'height': base_image["height"]
})

The cleanup logic is:

python
for img_info in content['images']:
    try:
        word_doc.add_picture(img_info['path'], width=Inches(4))
        os.remove(img_info['path'])
    except:
        pass

Technical Analysis

Images extracted from a PDF are written to the current working directory using deterministic names composed only of the page number, image index, and image extension. The files are opened in ordinary write mode, which truncates existing files and follows symbolic links.

The implementation does not use a private temporary directory, securely randomized names, exclusive file creation, or symbolic-link protections. Consequently, another local user who can write to the working directory can predict the filename and create a symbolic link before conversion begins.

Cleanup is also not guaranteed. The temporary image is removed only after word_doc.add_picture() succeeds. Because both insertion and deletion are inside a broad try/except block, any failure is silently ignored and can leave extracted images on disk. An exception elsewhere in conversion can have the same result.

Attack Path

  1. An attacker obtains write access to the directory from which the converter will run.
  2. The attacker predicts a generated filename, such as _temp_img_0_0.png.
  3. The attacker creates that path as a symbolic link to another file writable by the converter process.
  4. A victim runs the converter against a PDF whose first page contains an image with the matchi ...[truncated 955 chars]
Remediation
View remediation

Remediation Suggestions

  • Avoid writing extracted images to predictable paths in the current working directory.
  • Prefer passing image data directly to python-docx through an io.BytesIO stream:
python
from io import BytesIO

image_stream = BytesIO(image_bytes)
word_doc.add_picture(image_stream, width=Inches(4))
  • If filesystem-backed temporary files are required, create a private temporary directory with tempfile.TemporaryDirectory() and generate files inside it.
  • Ensure cleanup through a try/finally block or a temporary-directory context manager so that failures cannot leave extracted images behind.
  • Do not reuse existing paths, and avoid APIs or modes that follow attacker-created symbolic links. Where supported, use exclusive creation and no-follow protections.
  • Replace broad, silent except: handlers with specific exception handling and clear error reporting so cleanup and conversion failures remain visible.
  • Run conversion in a directory inaccessible to untrusted local users and under a minimally privileged account as defense in depth.
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

该技能的主目的与代码总体方向一致,都是PDF转Word并尝试保留部分格式,因此不属于完全不同用途。但声明明显夸大了实现能力:代码并没有真正“完整”或“精确”保留原始PDF格式。它主要基于PyMuPDF提取文本span后重建Word内容,且在重建时把同一行文本合并成一个run,只继承第一个span的字体和样式,这会丢失行内不同字体、字号、粗斜体、下划线、颜色等细粒度格式。段落格式也并非从PDF中提取,而是硬编码了首行缩进和1.5倍行距,没有实现声明中的段前段后间距等。表格和图片虽然有提取,但图片只按固定宽度插入,不保留页面位置布局。另有实现问题:convert_pdf_to_word中使用Pt设置默认样式,但Pt未在该作用域导入,可能导致运行报错。综合看,描述与代码在核心方向上相符,但在“精确完整保留格式”的程度以及额外批量/分页功能上存在实质不符,因此应判定为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description promises a full PDF-to-Word conversion capability with detailed formatting preservation. However, the supplied code chunk is a test harness rather than the conversion implementation itself. Its primary behavior is environment/setup validation: importing the converter module, checking for pdf2docx availability, listing PDFs in the current directory, and printing CLI usage examples. Because the actual code shown does not carry out the promised conversion behavior or formatting-preservation logic, the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

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.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file is entirely written in Chinese and does not provide any opt-in, alternative language, or explanation that the skill is region- or locale-specific. Under the language/locale policy rule, forcing a single language without user choice can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module docstring says it completely extracts alignment, paragraph formatting, first-line indent, and line spacing. However, the code later assigns a fixed first-line indent of 0.74 cm and fixed line spacing of 1.5 for generated paragraphs rather than deriving those values from the source PDF, so the documentation overstates what the code actually does.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module docstring is written entirely in Chinese and presents the skill as such without offering any language choice or stating that it is intentionally limited to a Chinese-speaking audience. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest advertises exact retention of paragraph formatting including 1.5 line spacing, before/after spacing, and a two-character first-line indent. In code, all non-title paragraphs are assigned the same fixed first-line indent and line spacing, and there is no extraction or application of paragraph before/after spacing from the PDF, so the behavior does not match the claimed precision.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill description promises preservation of mixed text formatting such as font name, size, bold, italic, underline, and color. This implementation concatenates all text in a grouped line into one run and applies only the first span's formatting, which loses intra-line style changes and prevents accurate preservation of mixed formatting.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The argparse description and argument help are user-facing natural language, but they are provided in Chinese only. This effectively requires a specific language/locale for use without giving users a choice or documenting a justified regional restriction.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest presents the conversion as precisely retaining document formatting including images. The code inserts every image at a constant width of 4 inches and does not preserve original placement or scaling, so image formatting is not retained as claimed.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.