T09 · Insecure Skill Coding Practices
- Location
kai_docx_generator/engine/template_filler.py:56- Finding
Unsafe XML Parsing of Untrusted DOCX Templates
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill appears to generate and fill Word documents as advertised, but it needs review because untrusted DOCX templates and image paths can expose local-file or resource-exhaustion risks.
Review before installing if you may process files from other people. Use this skill only in a sandbox or low-sensitivity workspace, avoid untrusted DOCX templates and Markdown image references until XML parsing, ZIP limits, and path containment are hardened, and pin dependency versions for reproducible installs.
kai_docx_generator/engine/template_filler.py:56Unsafe XML Parsing of Untrusted DOCX Templates
kai_docx_generator/engine/template_filler.py:138Unbounded DOCX Archive Decompression Permits Resource Exhaustion
kai_docx_generator/engine/docx_engine.py:251Image Path Validation Can Be Bypassed on Supported Platforms
pyproject.toml:10Dependency Resolution Is Mutable and Non-Reproducible
The description presents an end-user document generation/template-filling skill. However, the code chunk does not implement document generation or template filling itself. Instead, it is a test harness that validates whether .docx outputs exist and meet expected conditions such as valid ZIP structure, metadata, headings, bold text, placeholder replacement, and specific content/style checks. It also writes grading results and invokes a subprocess to test strict-mode behavior. While some checks relate to the declared domain of .docx validation, the primary purpose of this code is evaluation of another tool’s outputs, not performing the described skill. Therefore the behavior is materially different from the declared purpose.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def test_image_path_traversal_rejected(self):
"""路径穿越攻击应被拒绝"""
doc = self._make_doc_from_md("")
texts = [p.text for p in doc.paragraphs]
assert any("图片加载失败" in t for t in texts)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def test_image_path_traversal_rejected(self):
"""路径穿越攻击应被拒绝"""
doc = self._make_doc_from_md("")
texts = [p.text for p in doc.paragraphs]
assert any("图片加载失败" in t for t in texts)
The skill advertises shell execution and file read/write behavior through its documented commands, but it does not declare any explicit tool scope such as allowed-tools or permissions. That creates an authorization gap: an orchestrator or reviewer cannot easily constrain what filesystem and subprocess capabilities the skill expects, increasing the risk of overbroad access during execution.
Several triggers such as '生成文档' and 'fill template' are broad enough to match routine user requests that may not specifically intend .docx generation. Overbroad invocation can cause the agent to activate this skill unexpectedly, leading to unintended file creation, template processing, or handling of local document paths in contexts where a safer or simpler response would be appropriate.
This grading function goes beyond validating output artifacts and actively executes external code to test strict-mode behavior. That expands the attack surface substantially because running the skill's implementation during grading can trigger arbitrary behavior unrelated to document validation.
The subprocess is executed from a hard-coded absolute path outside the eval workspace, creating an unsafe trust boundary and making the grader depend on local host state. This can execute unexpected code from a developer machine path, break reproducibility, and expose host data or environment details if that path is manipulated or contains untrusted content.
The script launches an external Python process during grading, which means evaluation is not limited to passive inspection of generated .docx files. If this grader is run in an automated or shared environment, it will execute repository code from scripts/fill_template.py and inherit the risks of arbitrary code execution, side effects, and environment access.
f.write(data)
data_path = f.name
try:
result = subprocess.run(
["python", "scripts/fill_template.py", "templates/contract.docx",
"--data", data_path, "--output", "/tmp/eval8_strict_test.docx", "--strict"],
capture_output=True, text=True,
The trigger list includes generic phrases such as '生成文档' and 'fill template' that can match many ordinary document-related requests outside the narrow .docx use case. In an agent-routing system, overly broad activation can cause the wrong skill to engage, leading to unintended file handling, unexpected document generation behavior, or misuse of user content in contexts the user did not intend.
The documentation says to announce the recommended style using a Chinese-only message, which imposes a specific language regardless of the user's preferred locale. There is no opt-in, fallback, or statement that the skill is intended only for Chinese-language environments.
The manifest-style prompt "Generate a red-header official dispatch document" describes a general request rather than a clearly bounded invocation condition. It does not specify trigger scope, exclusions, or negative examples, so it could overlap with ordinary document-generation requests and lead to unintended activation.
The trigger list includes generic phrases such as "生成文档", "fill template", and "generate docx" that can match many routine document-related requests beyond narrowly scoped DOCX conversion or template filling. Overly broad activation can cause the wrong skill to auto-invoke, pulling user content into this skill unexpectedly and increasing the chance of unintended file generation, template processing, or mishandling of sensitive document data.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
{
"id": 5,
"name": "technical-spec-with-code",
"prompt": "把这段技术规范转成 Word 文档,保存到 /tmp/eval5.docx:\n\n# API 接口规范\n\n## 认证方式\n\n所有请求必须携带 `Authorization` header,格式为 `Bearer <token>`。\n\n## 请求示例\n\n```python\nimport requests\n\nresponse = requests.get(\n \"https://api.example.com/v1/users\",\n headers={\"Authorization\": \"Bearer your-token\"}\n)\nprint(response.json())\n```\n\n## 错误码\n\n| 错误码 | 说明 | 处理方式 |\n|--------|------|----------|\n| 400 | 请求参数错误 | 检查参数格式 |\n| 401 | 未授权 | 检查 token |\n| 429 | 请求过于频繁 | 等待后重试 |",
"expected_output": "使用 tech_spec 样式,代码块有等宽字体和灰色背景,表格正确渲染"
},
{
This Python file contains user-facing natural-language documentation exclusively in Chinese, including the module docstring and multiple explanatory comments. Under the language/locale policy rule, forcing a specific language without user opt-in or a documented region-specific justification is a policy concern.
This code file contains natural-language descriptions and help text entirely in Chinese, including the module docstring, argument descriptions, and error/output messages. The skill does not offer any language selection or indicate that it is intentionally region-specific, which can violate a language/locale policy requiring user choice or explicit justification.
This Python file contains user-facing natural-language strings and defaults that enforce a Chinese-specific typography choice, including the module description in Chinese and repeated hard-coded use of the East Asia font 'Microsoft YaHei'. Under the policy, forcing a specific language/locale without user opt-in can be a violation unless the locale constraint is clearly documented and justified; this file does not document such a justification.
The CLI docstring, argument descriptions, and user-facing messages are written entirely in Chinese, which imposes a specific language/locale on users. Under the stated policy, this is a natural-language policy violation unless the skill offers a language choice or clearly documents a justified region-specific constraint, neither of which appears here.
This code file contains natural-language strings for the CLI description, help text, and status/error messages entirely in Chinese. The policy for this category flags language/locale constraints when the skill forces a specific language without user opt-in, and there is no indication here that users can select another language or that the locale restriction is required.
This Python file contains user-facing descriptions, warnings, and console output entirely in Chinese, including the module docstring, CLI argument help, and runtime messages. Under the policy rule, forcing a specific language without user opt-in or a documented region-specific justification is a natural-language policy violation.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
output_path = f.name
try:
result = subprocess.run(
[sys.executable, os.path.join(SCRIPTS_DIR, "generate.py"), md_path, output_path],
capture_output=True, text=True
)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
output_path = f.name
try:
result = subprocess.run(
[sys.executable, os.path.join(SCRIPTS_DIR, "generate.py"), md_path, output_path],
capture_output=True, text=True
)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
output_path = f.name
try:
result = subprocess.run(
[sys.executable, os.path.join(SCRIPTS_DIR, "generate.py"), md_path, output_path],
capture_output=True, text=True
)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
with tempfile.NamedTemporaryFile(suffix=".docx", delete=False) as f:
output_path = f.name
result = subprocess.run(
[sys.executable, os.path.join(SCRIPTS_DIR, "generate.py"), "/nonexistent/file.md", output_path],
capture_output=True, text=True
)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
output_path = f.name
try:
result = subprocess.run(
[sys.executable, os.path.join(SCRIPTS_DIR, "fill_template.py"), self.TEMPLATE_PATH,
"--data", data_path, "--output", output_path],
capture_output=True, text=True
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
output_path = f.name
try:
result = subprocess.run(
[sys.executable, os.path.join(SCRIPTS_DIR, "fill_template.py"), self.TEMPLATE_PATH,
"--data", data_path, "--output", output_path],
capture_output=True, text=True
No suspicious patterns detected.