T09 · Insecure Skill Coding Practices
- Location
scripts/md2docx.py:1132- Finding
Unrestricted image retrieval enables SSRF, local image disclosure, and resource exhaustion
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill appears to be a real Markdown-to-DOCX converter, but its image handling and dependency setup are broad enough that users should review it before installing.
Install only if you are comfortable with the skill creating a cached Python environment and downloading dependencies. Avoid running it on untrusted Markdown unless remote image fetching is disabled or sandboxed, because image links may contact external or internal URLs and local image paths may be embedded into the output document.
scripts/md2docx.py:1132Unrestricted image retrieval enables SSRF, local image disclosure, and resource exhaustion
scripts/setup_env.py:25Unpinned dependencies are installed from a third-party package index
Referenced artifact was not completely inspected
3. **执行转换** — 用专用解释器 `~/.cache/mddocx/venv/bin/python` 运行内置脚本 `scripts/md2docx.py`;若 Markdown 结构特殊则参照下方格式规范编写自定义脚本
The skill describes capabilities to read and write files, execute shell commands, create environments, and access the network, but it does not declare any explicit tool scope or permissions boundaries. That mismatch increases the risk of over-privileged execution, making it easier for the skill to perform actions beyond what a user would reasonably expect from a Markdown-to-DOCX converter.
The description says the skill should activate not only for explicit commands like '/mddoc' but also for broad phrases such as '生成格式化文档' and even '把这个转成word' when the content is Markdown. These phrases are common in ordinary conversation and the file does not provide exclusion conditions or negative examples, increasing the risk of unintended invocation.
The description and formatting rules are written as fixed Chinese academic output requirements, including Chinese title, header, page-number, and naming conventions, without offering any language or locale choice. This can violate language/locale policy when users have not opted into Chinese-specific formatting behavior.
The environment setup flow creates a virtual environment and installs dependencies into a user cache directory, which introduces package installation and code execution behavior beyond straightforward file conversion. If dependency sources or versions are not tightly pinned and verified, this increases supply-chain and persistence risk on the user's machine.
The skill supports downloading remote images during conversion, which expands a nominally local document-conversion task into networked content retrieval. This can expose the host to SSRF-like behavior, unexpected outbound requests, metadata leakage, and processing of untrusted remote content when a user supplies Markdown containing attacker-controlled image URLs.
The skill omits a clear warning that conversion may download remote images referenced in Markdown. Users may believe they are performing a purely local conversion, while the skill silently makes outbound requests that can leak IP address, system behavior, or access internal network targets if attacker-controlled URLs are present.
All natural-language prompts in the eval file are written in Chinese, including a command-style invocation, which indicates the skill behavior is being evaluated only in a single language. There is no accompanying text offering language choice or documenting that the skill is intentionally limited to Chinese users, which can violate language/locale policy expectations.
The script's help text, status output, generated default filename, and document labels are all fixed in Chinese, with no option for users to select another language or locale. This is a natural-language policy concern because it imposes a specific language on all users without opt-in or documented justification.
The converter automatically fetches remote images referenced in Markdown over HTTP/HTTPS during document generation. This creates a server-side request capability from untrusted document content, which can leak network metadata, contact attacker-controlled hosts, and potentially access internal-only resources if the tool runs in a privileged environment.
Remote image downloads are performed silently, without disclosing that untrusted Markdown can trigger outbound network requests. In a conversion skill, this makes the SSRF/privacy risk more dangerous because users and operators may assume the tool only transforms local text into DOCX.
The image handler treats Markdown image paths as arbitrary local file paths and copies any existing file into the generated document. An attacker controlling Markdown content can cause unintended local file inclusion from the host filesystem, which may expose sensitive files if the converter runs with access to them.
The file’s natural-language documentation is entirely in Chinese and presents the script’s interface and status semantics in that language only, with no indication that language is configurable or intentionally region-scoped. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.
The skill is described as a local Markdown-to-docx converter, yet it provisions the network-capable requests library even though this script itself does not need it. Unnecessary networking dependencies enlarge the attack surface, enable unexpected outbound HTTP behavior in later code, and increase supply-chain risk for a skill whose context suggests offline document conversion.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
bool — True 表示依赖可用,False 表示缺失。
"""
code = 'import ' + ', '.join(REQUIRED_MODULES)
return subprocess.run([str(python), '-c', code],
capture_output=True).returncode == 0
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 2) venv 不存在 → 创建
if not py.is_file():
print(f'[mddoc] 创建虚拟环境: {venv}', file=sys.stderr)
subprocess.run([sys.executable, '-m', 'venv', str(venv)], check=True)
# 3) 依赖缺失 → 仅此时安装
pip = venv / bin_dir(venv) / ('pip.exe' if sys.platform == 'win32' else 'pip')
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 3) 依赖缺失 → 仅此时安装
pip = venv / bin_dir(venv) / ('pip.exe' if sys.platform == 'win32' else 'pip')
print(f'[mddoc] 安装缺失依赖: {PIP_PACKAGES}(镜像: {PIP_INDEX})', file=sys.stderr)
subprocess.run([str(pip), 'install', '--disable-pip-version-check',
'-i', PIP_INDEX]
+ PIP_PACKAGES.split(), check=True)
except subprocess.CalledProcessError as exc:
This JSON eval file contains invocation examples like '帮我把这份 Markdown 文件转成 docx 格式的 Word 文档' and '将下面这段 markdown 转成格式化的 Word 文档' without clearly constraining what exact phrases should activate the skill. In a manifest-like file, such broad everyday phrasing can overlap with ordinary user requests and does not provide exclusion conditions or a bounded trigger scope.
This markdown file is written entirely in Chinese, including the title and explanatory text, with no indication that language selection is optional or that the file is intended only for a Chinese-language audience. Under the policy rule for natural-language violations, a fixed language choice without opt-in can be considered a locale policy issue.
This markdown file is entirely natural-language content, and it forces a specific language/locale for readers with no opt-in or explanation. The policy explicitly calls for flagging language or locale constraints when the skill does not offer user choice or justify the restriction.
The script creates and saves a DOCX file to disk, potentially at a user-specified path, but aside from a final success message it does not provide any prior warning or explanatory comment near the write operation. Because file creation/modification is a safety-relevant action, some user disclosure should be present before the write occurs.
No suspicious patterns detected.