Back to skill

Security audit

Kai Docx Generator

Security checks for vulnerabilities and agentic risk

Overview

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.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
kai_docx_generator/engine/template_filler.py:56
Finding

Unsafe XML Parsing of Untrusted DOCX Templates

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
kai_docx_generator/engine/template_filler.py:138
Finding

Unbounded DOCX Archive Decompression Permits Resource Exhaustion

Content
View full analysis
Remediation
View remediation
MAX_MEMBERS: raise ValueError("Archive contains too many members") total_size = 0 seen = set() for info in infos: if info.filename in seen: raise ValueError("Archive contains duplicate member names") seen.add(info.filename) if info.file_size > MAX_MEMBER_SIZE: raise ValueError("Archive member is too large") total_size += info.file_size if total_size > MAX_TOTAL_SIZE: raise ValueError("Archive expands beyond the allowed size") if info.compress_size == 0: if info.file_size > 0: raise ValueError("Suspicious compression ratio") elif info.file_size / info.compress_size > MAX_COMPRESSION_RATIO: raise ValueError("Suspicious compression ratio") ``` Additional hardening should include: 1. Stream-copy unchanged members instead of loading the entire archive into a dictionary. 2. Limit the size of XML members before passing them to `lxml`. 3. Reject encrypted, unsupported, or malformed archive members. 4. Reject duplicate names and abnormal member counts. 5. Apply process-level memory, CPU, execution-time, and output-size limits. 6. Treat an oversized DOCX as invalid rather than merely issuing a warning. 7. Add regression tests using high-compression-ratio archives and excessive member counts. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
kai_docx_generator/engine/docx_engine.py:251
Finding

Image Path Validation Can Be Bypassed on Supported Platforms

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
pyproject.toml:10
Finding

Dependency Resolution Is Mutable and Non-Reproducible

Content
View full analysis
=1.1.0", "markdown-it-py>=3.0.0", "lxml>=4.9.0", "Pillow>=10.0.0", "pyyaml>=6.0", ] ``` The requirements file uses the same mutable constraints: ```text python-docx>=1.1.0 markdown-it-py>=3.0.0 lxml>=4.9.0 Pillow>=10.0.0 pyyaml>=6.0 ``` The Skill metadata also instructs the environment to install packages by name without locked versions or hashes: ```yaml install: - id: python-docx kind: uv package: python-docx label: "python-docx (core)" - id: markdown-it-py kind: uv package: markdown-it-py label: "markdown-it-py (parser)" - id: lxml kind: uv package: lxml label: "lxml (XML)" - id: Pillow kind: uv package: Pillow label: "Pillow (images)" - id: pyyaml kind: uv package: pyyaml label: "pyyaml (YAML)" ``` ### Technical Analysis The declared package names correspond to established public Python packages, and the audit found no evidence of typosquatting, dependency confusion, or deliberately malicious package sources. However, the use of minimum versions without upper bounds, a lockfile, or integrity hashes makes installations non-reproducible. Two installations performed at different times can resolve to different dependency code without any change to this repository. This increases exposure to: - A compromised future package release - An incompatible major release - A newly introduced transitive dependency - Security behavior changing across parser or image-library versions - Inconsistent audit and production environments The broad `lxml>=4.9.0` constraint is particularly relevant because XML parser behavior and security defaults may vary between version ...[truncated 1149 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (88)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · tests/test_docx_engine.py (reported line 331)May include surrounding context.

python
def test_image_path_traversal_rejected(self):
        """路径穿越攻击应被拒绝"""
        doc = self._make_doc_from_md("![test](../../../etc/passwd)")
        texts = [p.text for p in doc.paragraphs]
        assert any("图片加载失败" in t for t in texts)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · tests/test_docx_engine.py (reported line 337)May include surrounding context.

python
def test_image_path_traversal_rejected(self):
        """路径穿越攻击应被拒绝"""
        doc = self._make_doc_from_md("![test](../../../etc/passwd)")
        texts = [p.text for p in doc.paragraphs]
        assert any("图片加载失败" in t for t in texts)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

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.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

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.

Content

Scanner excerpt · evals-workspace/grade_evals.py (reported line 218)May include surrounding context.

python
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,

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

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.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · evals/evals.json (reported line 30)May include surrounding context.

json
{
    "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 样式,代码块有等宽字体和灰色背景,表格正确渲染"
  },
  {

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

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.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_cli.py (reported line 26)May include surrounding context.

python
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 call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_cli.py (reported line 273)May include surrounding context.

python
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 call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_cli.py (reported line 293)May include surrounding context.

python
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 call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_cli.py (reported line 42)May include surrounding context.

python
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 call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_cli.py (reported line 74)May include surrounding context.

python
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 call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · tests/test_cli.py (reported line 145)May include surrounding context.

python
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

Static analysis

No suspicious patterns detected.