Back to skill

Security audit

质量管理QC技能

Security checks for vulnerabilities and agentic risk

Overview

This QC chart skill is mostly purpose-aligned, but its template loading can read JSON files outside the intended template folder and its file-write behavior is under-scoped.

Review this skill before installing. It appears to be a normal QC chart generator, but use explicit trusted input and output paths, avoid template names containing path separators or .., and install dependencies from a trusted pinned environment.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/qc_chart_generator.py:451
Finding

Template Name Path Traversal Enables Unauthorized Local JSON File Access

Content
View full analysis

Vulnerability Details

File Location: scripts/qc_chart_generator.py:451-459
Vulnerability Type: Path traversal in template loading
Risk Level: Medium

Vulnerable Code

python
def load_template(template_name):
    """Load a predefined template."""
    template_dir = os.path.join(os.path.dirname(__file__), '..', 'assets', 'templates')
    template_path = os.path.join(template_dir, f'{template_name}.json')
    
    if not os.path.exists(template_path):
        return None
    
    with open(template_path, 'r', encoding='utf-8') as f:
        template = json.load(f)

Technical Analysis

The template_name value originates from the command-line --data argument when --template is enabled. It is appended with .json and joined to the intended template directory without validation, canonicalization, or a containment check.

os.path.join() does not prevent traversal sequences such as ../. An attacker able to control the command arguments can therefore construct a path that escapes assets/templates and points to another readable JSON file. The existence check does not provide protection because it is performed on the attacker-influenced path.

The appended .json suffix limits the issue to paths that resolve to filenames ending in .json, but it does not guarantee that the selected file resides in the authorized template directory.

Attack Path

  1. The attacker identifies a JSON file readable by the account running the Skill.
  2. The attacker calculates a relative path from assets/templates to that file, omitting the final .json suffix.
  3. The attacker invokes the program with template mode enabled, for example:
    bash
    python scripts/qc_chart_generator.py \
      --chart-type fishbone \
      --template \
      --data '../../../path/to/sensitive_file' \
      --output /tmp/result.png
    
  4. The application appends .json, resolves the traversal path t ...[truncated 793 chars]
Remediation
View remediation

Remediation Suggestions

  • Restrict template names to a conservative allowlist pattern such as ^[A-Za-z0-9_-]+$.
  • Resolve the template directory and candidate path to canonical absolute paths before opening the file.
  • Verify that the resolved candidate remains a descendant of the template directory.
  • Reject absolute paths, path separators, . components, and .. components.
  • Consider selecting templates only from an enumerated list of known files.

Example hardening approach:

python
import re
from pathlib import Path

def load_template(template_name):
    if not re.fullmatch(r'[A-Za-z0-9_-]+', template_name):
        raise ValueError('Invalid template name')

    template_dir = (
        Path(__file__).resolve().parent.parent / 'assets' / 'templates'
    ).resolve()
    template_path = (template_dir / f'{template_name}.json').resolve()

    if template_dir not in template_path.parents:
        raise ValueError('Template path escapes the template directory')

    if not template_path.is_file():
        return None

    with template_path.open('r', encoding='utf-8') as file:
        template = json.load(file)

    return template.get('data', template)

T08 · Insecure Dependencies

Note
Location
scripts/qc_chart_generator.py:11
Finding

Unpinned Third-Party Dependency Installation Guidance Creates Supply-Chain Exposure

Content
View full analysis

Vulnerability Details

File Location: scripts/qc_chart_generator.py:11-25
Vulnerability Type: Unpinned and unverifiable third-party dependency installation
Risk Level: Low

Vulnerable Code

python
try:
    import matplotlib
    matplotlib.use('Agg')
    import matplotlib.pyplot as plt
    import matplotlib.font_manager as fm
    import numpy as np
    import pandas as pd
except ImportError as e:
    print(json.dumps({
        "status": "error",
        "message": f"Missing dependency package: {str(e)}",
        "solution": "Install with: pip install matplotlib numpy pandas"
    }))
    sys.exit(1)

The original source presents the error and installation guidance in another language; the wording above is translated to English without changing the installation command or behavior.

Technical Analysis

The program depends on matplotlib, numpy, and pandas, but directs users to install them without version constraints or package-integrity hashes. Dependency resolution therefore selects whichever versions are currently available from the configured package index.

This creates avoidable supply-chain and reproducibility risks. If the configured index, mirror, name-resolution configuration, or a selected package release is compromised, following the emitted command can install attacker-controlled code. Python package installation can execute build-system or installation logic with the privileges of the invoking user.

The project also lacks a reviewed lock file or requirements file in the audited directory. In addition, SKILL.md states that Python 3 is already available but does not accurately declare these third-party runtime dependencies. pandas is imported but not used by the script, unnecessarily increasing dependency surface.

Attack Path

  1. A user runs the script in an environment where one or more dependencies are absent.
  2. The script emits the unpinned command ...[truncated 1322 chars]
Remediation
View remediation

Remediation Suggestions

  • Declare all runtime dependencies in a maintained requirements or lock file.
  • Pin dependencies to reviewed versions and include cryptographic hashes.
  • Install with hash verification, for example:
    bash
    python -m pip install --require-hashes -r requirements.txt
    
  • Use a trusted and explicitly configured package index or an internally controlled package mirror.
  • Perform dependency vulnerability and provenance scanning in continuous integration.
  • Document the required dependencies accurately in SKILL.md.
  • Remove the unused pandas import and dependency unless it is genuinely required.
  • Avoid presenting an unconstrained installation command as the primary remediation for missing packages.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (6)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill invokes a local Python script and documents output/export behavior, which implies file read/write capabilities, but it does not declare any tool scope or permissions boundaries. This can lead to overbroad execution in an agent environment, where the runtime may allow unintended file access or path usage beyond what users expect.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger conditions are broad enough to overlap with common data analysis, visualization, and diagnosis requests, increasing the chance that the skill auto-activates in contexts the user did not intend. Because the skill can run scripts and write output files, accidental invocation expands the operational risk and may cause unexpected local file creation or processing of sensitive data.

Content

No source excerpt is available for this finding.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The documentation mentions exporting data and generating output files but does not clearly warn that local files will be written or that an existing output path may be overwritten. In agent-driven environments, unclear file-write behavior can surprise users, cause accidental data loss, or write artifacts into sensitive locations if paths are not constrained.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file contains user-facing instructional content exclusively in Chinese, and nowhere indicates that the skill is region-specific or that alternate language support is optional. Under the natural-language policy rule, forcing a specific language without user opt-in can be a locale policy violation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.