Back to skill

Security audit

ISO20000认证助手/ISO20000-certificate-assistant

Security checks for vulnerabilities and agentic risk

Overview

The skill’s ISO document-analysis purpose is coherent, but legacy .doc parsing can leave a full plaintext copy of confidential client documents on disk without clear cleanup or user control.

Review before installing if you will process confidential client documents. Prefer .docx inputs, keep work in a controlled directory, and check/delete generated .txt conversion files and logs after use. The skill does not show exfiltration, remote code loading, or system persistence, but its local data-retention behavior should be fixed or clearly disclosed.

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/parse_docx.py:133
Finding

Persistent Plaintext Copy of Confidential Client Documents

Content
View full analysis

Vulnerability Details

File Location: scripts/parse_docx.py, lines 133–153
Vulnerability Type: Insecure storage and handling of sensitive temporary data
Risk Level: Medium

Vulnerable Code

python
def parse_doc_with_antiword(file_path):
    """Try to convert .doc file using antiword"""
    try:
        # Try antiword first
        output_file = file_path + '.txt'
        logger.info(f"Attempting to convert .doc to .txt using antiword")
        
        import subprocess
        result = subprocess.run(
            ['antiword', file_path],
            capture_output=True,
            text=True,
            timeout=30
        )
        
        if result.returncode == 0:
            # Save converted text
            with open(output_file, 'w', encoding='utf-8') as f:
                f.write(result.stdout)
            logger.info(f"Successfully converted .doc to {output_file}")
            return parse_txt(output_file)

Technical Analysis

When a legacy .doc file is processed, its complete extracted content is written to a predictable path formed by appending .txt to the original path. The resulting plaintext file is created using default process permissions and is not deleted after parsing.

The project is explicitly intended to process client documents that may contain confidential company information, personal data, and business metrics. Creating an additional persistent plaintext copy unnecessarily expands the sensitive-data footprint. The predictable filename also makes the copy easy to locate.

The subprocess.run invocation itself does not present command injection in this code because it uses an argument list and does not enable a shell. The vulnerability is the subsequent insecure storage and retention of the conversion output.

Attack Path

  1. A user provides a confidential legacy Word document such as client-audit.doc.
  2. The parser invokes antiword and captures the document’s complete plaintext content.
  3. Th ...[truncated 1114 chars]
Remediation
View remediation

Remediation Suggestions

  1. Avoid creating an intermediate file. Pass the captured output directly to the existing structure extractor:
python
if result.returncode == 0:
    logger.info("Successfully extracted text from .doc file")
    return extract_structure(result.stdout, file_path)
  1. If disk-backed conversion is operationally necessary, create the file with tempfile.NamedTemporaryFile in a protected temporary directory and enforce owner-only permissions such as 0600.

  2. Delete every temporary artifact in a finally block so cleanup occurs after successful parsing and after exceptions:

python
import os
import tempfile

temp_path = None
try:
    with tempfile.NamedTemporaryFile(
        mode='w',
        encoding='utf-8',
        suffix='.txt',
        delete=False
    ) as temp_file:
        temp_path = temp_file.name
        temp_file.write(result.stdout)

    os.chmod(temp_path, 0o600)
    return parse_txt(temp_path)
finally:
    if temp_path and os.path.exists(temp_path):
        os.remove(temp_path)
  1. Do not place temporary plaintext beside the source document or use a filename derived predictably from it.

  2. Document the data-retention policy and verify through automated tests that no converted plaintext remains after success, parser errors, timeouts, or interrupted processing.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (15)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill instructs the agent to invoke shell commands and read/write user-derived files, but it declares no explicit tool scope or permission boundaries. That creates a real least-privilege failure: an agent runtime may expose broader file-system or command execution capability than users expect, increasing the risk of unintended command execution, access to unrelated files, or unsafe document conversion/parsing behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill processes uploaded client documents and extracts internal structure/content, yet it provides no explicit warning about handling potentially confidential business information or personal data. In a certification-assistance context, documents are likely to contain sensitive operational details, so users may unknowingly expose data to parsing, storage, logging, or downstream generation steps without informed consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

This markdown file demonstrates the skill generating output documents such as a "整改版.docx" immediately after analysis, but it does not warn the user about data-handling or file-creation implications of that behavior. For markdown files, SQP-2 applies when the description omits warnings about behaviors that could affect user data or system integrity.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The file is described as providing bilingual Chinese and English templates, but the sections_en entries under the English headings contain Chinese text rather than English content. This creates a language/locale policy issue because users expecting English output are not actually given a meaningful language option or opt-in choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This JSON manifest/template file contains human-readable template content predominantly in Chinese, including procedure names and section bodies, while the surrounding metadata and notes are partly in English. Because the file provides no opt-in, language selection, or justification that it is intended only for a Chinese-speaking or region-specific context, it can violate the policy against forcing a specific language without user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code generates user-facing document text in Chinese, including review/approval labels, with no indication that the skill is limited to a Chinese-language workflow or that users can opt into another language. That creates a natural-language locale policy concern because the skill forces a specific language by default.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

A certification-assistant skill is expected to analyze documents, but spawning an external binary through subprocess introduces host-level execution capability that is not inherent to document gap analysis itself. This is especially notable because the manifest does not mention shelling out to local tools or requiring system command execution.

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 · scripts/parse_docx.py (reported line 139)May include surrounding context.

python
logger.info(f"Attempting to convert .doc to .txt using antiword")
        
        import subprocess
        result = subprocess.run(
            ['antiword', file_path],
            capture_output=True,
            text=True,

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The generation workflow creates output files populated with client-derived content, but the skill does not warn users that sensitive source material may be reproduced into new files and formats. This increases the risk of accidental propagation of confidential information into generated documents, exports, or shared artifacts, especially because the skill explicitly auto-fills templates from uploaded material.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill documentation earlier states that all 28 required procedures have generic versions and Step 3 says users can choose from 28 generic templates. The initialization message instead promises generation of '26个程序文件', which is a direct inconsistency in the skill's stated capability and can mislead users about what the skill actually supports.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

Natural-language policy violations include forcing a specific language without user opt-in. The examples and assistant introduction are written in Chinese and do not indicate that the user may choose another language, which can be interpreted as a language/locale constraint without explicit opt-in.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
99% confidence
Finding

The file-level description claims these are bilingual templates, and the nested field names sections_en plus English titles imply the content should be English. However, the body text under the English section remains in Chinese, which contradicts the apparent documentation/structure of the data rather than merely being incomplete translation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This manifest-style JSON embeds Chinese-language fields alongside English content, but it does not state that Chinese output is optional, user-selected, or limited to a specific regional deployment. Under the policy, locale-specific content can be a concern when the file appears to prescribe a language without opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

In load_template, the default parameter is language: str = "zh", and the docstring describes Chinese as the default behavior. This is a natural-language locale policy concern because the skill defaults to a specific language rather than explicitly offering or requiring user choice at the interface level.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The manifest frames the skill as helping with ISO20000 gap analysis, compliance checking, and document generation, which implies document processing but not necessarily creation of local log files as a side effect. This script always writes a persistent log file and, in .doc handling, creates an intermediate .txt file, expanding behavior beyond pure parsing/analysis.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.