T09 · Insecure Skill Coding Practices
- Location
scripts/md2word.py:153- Finding
Unrestricted External Image Downloads Enable SSRF and Resource Exhaustion
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Markdown-to-Word skill does what it claims, but it processes document content with broad default network, local-file, and SVG rendering authority that users should review before installing.
Install only if you trust the Markdown files and SVG content you will convert, or run it in a restricted environment with no internal-network access and limited filesystem access. Be especially careful with third-party Markdown because image links can trigger outbound requests and local image paths can embed readable local images into the generated DOCX.
scripts/md2word.py:153Unrestricted External Image Downloads Enable SSRF and Resource Exhaustion
scripts/md2word.py:907Markdown-Controlled Paths Can Read and Embed Arbitrary Local Images
scripts/svg2png.js:57Untrusted Inline SVG Is Loaded in Chromium with the Browser Sandbox Disabled
SKILL.md:18Installation Instructions Use Unpinned Third-Party Dependencies
声明的核心功能是“Markdown转Word文档”,即应当接收 Markdown 并生成排版后的 Word 文档。但该代码块的主功能完全不同:它读取 .docx 模板文件,抽取格式参数并导出 YAML 配置,服务于 md2word 配置生成流程。虽然这可能是 Markdown 转 Word 系统的辅助工具,但就该代码块本身而言,既不解析 Markdown,也不生成 Word 文档,因此与声明的主要用途存在明显不一致。未见敏感权限或恶意行为,但功能方向属于模板配置提取而非文档转换。
声明描述的是文档处理技能:输入应为 Markdown,输出应为 Word,并强调中文排版规范与预设格式。代码中完全没有 Markdown 解析、Word 文件生成、文档模板、排版规则或中文格式处理逻辑。相反,代码仅处理 SVG 文件,启动 Puppeteer 打开包含 SVG 的 HTML 页面并截图导出为 PNG,且包含 DPI 控制和目录批量转换功能。这说明其主要目的与声明严重不符,属于明显的描述与行为不一致。
This change re-enables default network access to download remote images, which is risky for a Markdown-to-Word skill because untrusted input can now cause outbound requests. That behavior can expose internal network reachability, disclose environment/IP information to third parties, and violate least-privilege expectations for a formatting tool.
The changelog documents that the skill automatically downloads external URL images during Markdown conversion, which adds active network-fetch behavior beyond simple local document formatting. When processing untrusted Markdown, this can trigger SSRF-like requests, leak IP/network metadata, and cause the agent to contact attacker-controlled hosts without explicit user intent at the execution point.
The changelog entry introducing automatic remote image downloads does not itself present a direct warning alongside the behavior change, increasing the chance that operators miss the privacy and network implications. For a skill that may process third-party Markdown, insufficient inline warning contributes to unsafe use by hiding that untrusted content can trigger outbound requests.
This file's natural-language content is fully Chinese, including headings and operational notes, with no indication that users may choose another language. Under the language/locale policy rule, forcing a specific language without opt-in is a policy concern unless the locale restriction is explicitly documented and justified.
The manifest describes a skill that converts Markdown into professionally formatted Word documents with Chinese typography presets. DEC-004 states the implementation downloads HTTP/HTTPS images from external URLs via urllib.request, which introduces network access beyond local document conversion and formatting. While image handling is relevant to document conversion, external network retrieval is a distinct capability not declared in the manifest description.
The README explicitly advertises automatic embedding of external URL images but does not warn users that conversion may trigger outbound network requests to third-party hosts. In document-processing workflows, this can leak sensitive document context, user IP/network metadata, or cause unintended access to attacker-controlled resources, so the missing disclosure is a real security weakness in user guidance.
The skill documentation declares significant capabilities—local script execution, external subprocess invocation, environment-variable reads, file read/write, and default-enabled network access to arbitrary URLs—but does not define an explicit tool scope such as permissions or allowed-tools. This creates a real least-privilege and review problem: an agent or user may invoke the skill without a machine-readable boundary, increasing the chance of unintended shell, filesystem, or network use.
The preset is named and described exclusively as a Chinese legal-document format, with Chinese-specific font and formatting assumptions. Under the policy, forcing a specific language or locale without opt-in or an explicit documented regional/compliance justification is a natural-language policy concern.
This YAML preset is explicitly tailored to Chinese-language document output, including a Chinese-only name/description, Chinese quote conversion, and Chinese-specific fonts such as 微软雅黑 and 仿宋. Because the file does not offer any language choice or document a justified region-specific restriction, it creates a locale policy concern by implicitly forcing one language/formatting convention.
Lines L001-L003 describe the theme as specifically aligned to domestic Chinese academic formatting conventions, using Chinese typography requirements and presenting them as the default behavior. This can constitute a language/locale policy issue because it enforces a specific locale and document standard without an explicit opt-in or clearly stated region-specific limitation.
This markdown file contains user-facing natural-language instructions exclusively in Chinese, and nowhere indicates that other languages are supported or that the language is a documented, justified locale constraint. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern.
The entire markdown file, including headings, instructions, and examples, is presented only in Chinese, with no indication that users may choose another language or that the skill is intentionally limited to a Chinese-language audience. Under the stated policy, forcing a specific language without opt-in is a natural-language policy violation.
The file’s title and descriptive content are entirely in Chinese, and there is no indication that the skill supports other languages or that Chinese is an explicitly user-selected option. Under the policy, forcing a specific language without opt-in is a natural-language policy concern unless the locale restriction is documented and justified.
The entire reference is written only in Chinese, including all operational instructions and configuration explanations, with no indication that users may choose another language or that the skill is intentionally limited to a Chinese-only audience. Under the policy rule for language/locale constraints, this appears to impose a specific language without user opt-in or explicit justification.
This code file contains natural-language documentation and runtime messages exclusively in Chinese, with no indication that users can choose another language or locale. That can violate a language/locale policy when the skill is expected to operate in a broader environment without explicit opt-in.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
cmd.extend(["-c", cfg])
print(f"🔧 执行命令: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if result.returncode != 0:
print(f"⚠️ mmdc 命令执行失败: {result.stderr}")
The skill is described as converting Markdown to professionally formatted Word documents, but this module executes a local external program (mmdc) via subprocess.run. Spawning subprocesses is a broader capability than ordinary document formatting logic and is not explicitly justified in the stated manifest purpose.
The executable path used in cmd can come directly from the MMDCCMD environment variable, allowing an attacker who controls the process environment to cause execution of an arbitrary program. In an agent or plugin environment where untrusted users may influence runtime configuration, this becomes code execution in the context of the host process.
cmd.extend(["-c", cfg])
print(f"🔧 执行命令: {' '.join(cmd)}")
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
if result.returncode != 0:
print(f"⚠️ mmdc 命令执行失败: {result.stderr}")
This Python file contains user-facing descriptions and messages entirely in Chinese, including module docstrings and CLI help text, which indicates a fixed language experience. Under the policy, forcing a specific language without user opt-in or a documented justification is a natural-language policy violation.
The command-line interface presents its description, argument help, and output messages only in Chinese. Because these are end-user visible strings and no language choice or locale justification is provided in the file, this violates the language/locale policy criteria.
This code file contains natural-language documentation and behavior descriptions exclusively in Chinese, including the module docstring and comments describing its purpose. Under the policy rule, forcing a specific language without opt-in or documenting a justified locale-specific scope is a language/locale policy violation.
The print statement emits a user-visible status message only in Chinese. Because the file does not offer language choice or explain that the tool is intentionally Chinese-only, this hardcoded locale creates a natural-language policy issue.
The function explicitly performs outbound HTTP(S) requests to fetch images referenced in Markdown and then embeds the returned content into the generated document. In a Markdown-to-Word converter this creates an SSRF/privacy boundary issue: opening attacker-supplied Markdown can trigger network access to arbitrary hosts, leak the user's IP and environment metadata, and pull untrusted content into the workflow without explicit consent.
No suspicious patterns detected.