Back to skill

Security audit

ISO9001认证助手/ISO9001-certificate-assistant

Security checks for vulnerabilities and agentic risk

Overview

The skill’s ISO document workflow is coherent, but its document-generation script can overwrite arbitrary writable files if given an unsafe output path.

Review this skill before installing in an environment with important writable files. Use it only on intended uploaded documents, direct outputs to a dedicated folder, avoid absolute or traversal paths, and confirm files are not being overwritten. Redact unnecessary confidential or personal information from company documents before processing.

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/generate_document.py:104
Finding

Caller-Controlled Output Path Allows Arbitrary File Overwrite

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_document.py:35-43, scripts/generate_document.py:49-70, and scripts/generate_document.py:104-131
Vulnerability Type: Unrestricted file write and arbitrary file overwrite
Risk Level: Medium

Vulnerable Code

The output path is accepted directly from a command-line argument:

python
# Generate or rewrite mode
template_id = sys.argv[1]
output_path = sys.argv[2]

The caller-controlled path reaches truncating file-write operations without validation or confinement:

python
def generate_template(template_data, output_path):
    """Generate a blank template document"""
    print(f"[INFO] Generating template to {output_path}...")
    
    # Simplified: just write the template content as text
    with open(output_path, 'w', encoding='utf-8') as f:
        f.write(f"# {template_data.get('title_zh', '')} / {template_data.get('title_en', '')}\n\n")
        f.write(f"Clause: {template_data.get('clause', '')}\n\n")
        
        for section in template_data.get("sections", []):
            f.write(f"## {section.get('heading_zh', '')} / {section.get('heading_en', '')}\n")
            f.write(f"{section.get('content_zh', '')} / {section.get('content_en', '')}\n\n")

The rewrite path contains the same unsafe sink:

python
def rewrite_document(parsed_data, template_data, gaps, output_path):
    """Rewrite existing document based on template and gap analysis"""
    print(f"[INFO] Rewriting document to {output_path}...")
    
    # Simplified: merge parsed data with template
    with open(output_path, 'w', encoding='utf-8') as f:
        f.write(f"# {template_data.get('title_zh', '')} / {template_data.get('title_en', '')}\n\n")
        f.write(f"Based on: {parsed_data.get('structure', {}).get('file_name', 'Unknown')}\n\n")
        
        for section in template_data.get("sections", []):
            f.write(f"
...[truncated 3412 chars]
Remediation
View remediation

Remediation Suggestions

  1. Define a dedicated, minimally privileged output directory and resolve all requested output names relative to it.
  2. Canonicalize both the output root and candidate path with pathlib.Path.resolve(), then verify that the candidate remains beneath the approved root.
  3. Reject absolute paths, traversal components, device paths, and unexpected file extensions.
  4. Prevent silent replacement by opening new files in exclusive creation mode (x) or requiring explicit, trusted overwrite authorization.
  5. Defend against symbolic-link attacks by rejecting symlink targets and, where supported, using operating-system flags such as O_NOFOLLOW.
  6. Run the Skill under a dedicated account with write permission only to its output directory.
  7. Use atomic creation in the approved directory and rename the completed file into place only after successful generation.
  8. Add tests covering absolute paths, ../ traversal, existing-file collisions, symbolic links, and paths that resolve outside the output root.

Example confinement logic:

python
from pathlib import Path

OUTPUT_ROOT = Path("generated_documents").resolve()

def safe_output_path(requested_name):
    candidate_input = Path(requested_name)
    if candidate_input.is_absolute() or ".." in candidate_input.parts:
        raise ValueError("Invalid output path")

    candidate = (OUTPUT_ROOT / candidate_input).resolve()
    if candidate != OUTPUT_ROOT and OUTPUT_ROOT not in candidate.parents:
        raise ValueError("Output path escapes the approved directory")

    if candidate.suffix.lower() not in {".txt", ".md", ".docx"}:
        raise ValueError("Unsupported output extension")

    candidate.parent.mkdir(parents=True, exist_ok=True)
    return candidate

The returned path should then be created exclusively or passed through an explicit trusted overwrite policy.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs the agent to run local scripts that read uploaded Word files and generate new documents, but it declares no explicit tool scope or permission boundaries. Without an allowlist for file access and execution, the agent may be granted broader read/write capability than users expect, increasing the risk of unauthorized file access or overwriting files if the skill is misused or the surrounding runtime is permissive.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly asks users to upload company Word documents for parsing, gap analysis, and document generation, but it does not prominently warn that those files may contain confidential business information or personal data that will be processed and reused in generated outputs. In this context, the risk is elevated because ISO/QMS documents commonly contain internal procedures, employee names, customer details, and operational metrics, so users may expose sensitive data without informed consent or minimization safeguards.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The metadata states the templates' language is fixed as "bilingual (Chinese/English)". Under the policy, forcing a specific language or locale without explicit user opt-in can be a natural-language policy violation unless the constraint is clearly documented as justified for a region-specific use case.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This JSON includes natural-language values that are exclusively in Chinese for some required document names, while the file does not state that the skill is limited to Chinese-speaking users or provide an opt-in language choice. That can create a locale-policy issue if the skill consumes or presents these strings to users without allowing language preference selection.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.