Back to skill

Security audit

Data Chart Tool

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent chart-generation tool, but its Python import path handling can load attacker-controlled local code and its licensing setup has risky secret-handling and authorization weaknesses.

Review before installing. Use it only in an isolated Python environment, avoid running it from shared writable directories, do not persist `SKILL_LICENSE_SECRET` in shell startup files, and be aware that the paid-feature license check is weak. The import-path issue should be fixed before using this on a multi-user system or with sensitive data.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T07 · Tool Hijacking and Spoofing

Error
Location
source/data_visualizer.py:14
Finding
Arbitrary Code Execution Through an Attacker-Controlled Python Import Path<![CDATA[ ## Vulnerability Details **File Location**: `source/data_visualizer.py`, lines 14-21 **Vulnerability Type**: Python module search-path hijacking **Risk Level**: High ### Vulnerable Code ```python workspace_root = Path(__file__).resolve().parents[3] if str(workspace_root) not in sys.path: sys.path.insert(0, str(workspace_root)) try: from skills.shared.license_manager import LicenseValidator, LicenseVerificationError LICENSE_AVAILABLE = True except ImportError: ``` ### Technical Analysis The program derives a directory three levels above its own file and places that directory at the beginning of `sys.path`. In the audited deployment layout, the resulting directory is `/tmp`. Python gives the first matching location in `sys.path` precedence during module resolution. Consequently, the subsequent import of `skills.shared.license_manager` can load a module located under `/tmp/skills/shared/` rather than a trusted module distributed with the application. The imported module is not present in the audited project. Its top-level code would execute immediately when the visualization program starts. This creates a local module-hijacking condition whenever another user or process can create the expected package structure in the selected parent directory. ### Attack Path 1. An attacker obtains permission to create files under the shared `/tmp` directory. 2. The attacker creates `/tmp/skills/shared/license_manager.py` and any package files required by the active Python version. 3. The malicious module defines the names expected by the application so that the import appears successful. 4. A victim launches `source/data_visualizer.py`. 5. The application prepends `/tmp` to `sys.path`. 6. Python imports the attacker-controlled license module. 7. Top-level code in that module executes with the victim process's permissions before normal chart processing begins. ### Impact Assessment Successful exploitation provides arbitrary Python code execution ...[truncated 426 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Package the license-validation implementation inside the installed project and import it with a package-relative import. - Do not add `/tmp`, another shared writable directory, or a dynamically derived untrusted parent directory to `sys.path`. - Install the application as a proper Python package in an isolated virtual environment. - If an external shared module is unavoidable, resolve it from a fixed, administrator-controlled directory and verify ownership and permissions before loading it. - Consider launching Python with isolated-path protections where operationally appropriate. - Add a startup test that rejects module origins outside an explicit allowlist. After importing, the application can inspect the module's resolved file path and terminate if it is outside the trusted installation directory. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
source/data_visualizer.py:257
Finding
Premium License Verification Fails Open on Unexpected Errors<![CDATA[ ## Vulnerability Details **File Location**: `source/data_visualizer.py`, lines 257-278 **Vulnerability Type**: Fail-open authorization control **Risk Level**: Medium ### Vulnerable Code ```python try: if args.license: validator = LicenseValidator( license_path=args.license, secret_key=os.getenv('SKILL_LICENSE_SECRET') ) validator.get_valid_license(skill_name='data-chart-tool') print("Premium license verification succeeded") elif args.type == 'scatter': print("The scatter chart requires a premium license") sys.exit(1) except LicenseVerificationError as e: print(f"License verification failed: {e}") sys.exit(1) except Exception as e: if args.type == 'scatter': print("The license system is unavailable; scatter remains enabled") pass ``` The displayed status messages have been translated into English; the control flow is unchanged from the audited source. ### Technical Analysis The code correctly terminates when it receives the expected `LicenseVerificationError`, but it suppresses every other exception when the requested chart type is `scatter`. Execution then continues into data loading and chart rendering. This is a fail-open authorization design: availability of the premium operation is granted when the authorization component cannot produce a trustworthy decision. The issue is also reachable when the shared license module cannot be imported. In that case, `LICENSE_AVAILABLE` is set to false, but the variable is never enforced. If a user supplies `--license`, evaluating the undefined `LicenseValidator` name raises an exception. The broad `except Exception` handler catches that failure and permits scatter-chart generation. ### Attack Path 1. The shared license module is absent, broken, replaced, or otherwise causes an unexpected exception. 2. A user invokes the tool with `--type scatter` and supplies any value through `--license`. 3. Con ...[truncated 902 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Fail closed whenever premium authorization cannot be completed. - Check `LICENSE_AVAILABLE` before processing premium operations and terminate with a nonzero status when the validator is unavailable. - Replace the broad fail-open handler with explicit termination: ```python except LicenseVerificationError as exc: raise SystemExit(f"License verification failed: {exc}") except Exception: raise SystemExit("License verification is unavailable") ``` - Verify the license before performing any premium operation or reading unnecessary user data. - Require a nonempty secret and reject missing or malformed license configuration explicitly. - Catch only documented validation exceptions where possible; log unexpected exceptions without granting access. - Add automated tests for missing modules, undefined validators, malformed license files, absent secrets, expired licenses, invalid signatures, and unexpected validator failures. ]]>

T08 · Insecure Dependencies

Note
Location
install.sh:18
Finding
Installation Uses Unpinned Third-Party Dependencies<![CDATA[ ## Vulnerability Details **File Location**: `install.sh`, line 18 **Vulnerability Type**: Unpinned dependency installation **Risk Level**: Low ### Vulnerable Code ```bash pip install matplotlib pandas openpyxl ``` The same unpinned installation command is also documented in `SKILL.md` at line 108. ### Technical Analysis The installation script retrieves the latest versions selected by the configured Python Package Index at installation time. It does not specify reviewed versions, cryptographic hashes, an approved package index, or an isolated environment. This does not establish that any named dependency is currently malicious. It does mean that installation behavior is mutable after the project has been audited. A future compromised release, compromised package source, or incompatible dependency update could be installed without a corresponding change to this repository. The script checks for `python3` but invokes the generic `pip` executable. That executable may belong to a different interpreter or may be replaced earlier in the user's `PATH`. ### Attack Path 1. A dependency release or configured package source is compromised, or an unexpected future version is published. 2. A user runs `install.sh`. 3. The generic `pip` command resolves the unpinned dependency from the active package source. 4. Installation executes package build or installation behavior and places the package into the active Python environment. 5. The compromised or incompatible dependency executes when imported by the visualization tool. Alternatively, a manipulated `PATH` could cause the script to invoke an unintended executable named `pip`. ### Impact Assessment A compromised dependency or substituted installer could execute code with the privileges of the user running the installation script. It could also affect other applications if packages are installed globally or into a shared environment. The practical likelihood is lower than the other findings because th ...[truncated 101 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin reviewed direct and transitive dependency versions in a lock file. - Require cryptographic hashes for downloaded distributions where supported. - Use `python3 -m pip` instead of the generic `pip` command so installation uses the interpreter that was checked. - Create and activate a dedicated virtual environment rather than modifying the global Python environment. - Use a trusted, explicitly configured package index and disable unexpected extra indexes. - Prefer prebuilt, reviewed wheels when practical and verify the lock file in continuous integration. - Add routine dependency vulnerability scanning and a controlled process for updating pinned versions. - Update `SKILL.md` so its documented installation procedure uses the same hardened dependency workflow. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Session Persistence

Medium
Category
Rogue Agent
Content
4. **安装**:
   ```bash
   # 复制许可证到用户目录
   mkdir -p ~/.data-chart-tool
   cp /path/to/license.json ~/.data-chart-tool/license.json
   ```
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
4. **安装**:
   ```bash
   # 复制许可证到用户目录
   mkdir -p ~/.data-chart-tool
   cp /path/to/license.json ~/.data-chart-tool/license.json
   ```
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The document instructs users to persist a secret signing key in shell startup files, which increases the chance of credential exposure through dotfile sync, backups, shell history mishandling, process inheritance, or accidental disclosure to other local users and tools. In this skill's context, the risk is amplified because the same secret appears to be shared with customers for offline verification, so compromise of that secret can undermine the licensing mechanism and enable forged licenses.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The prominent user-facing description and marketing copy are entirely in Chinese, and the document does not indicate that other languages are supported or that Chinese is required for a region-specific purpose. Under the policy, mandating a specific language without opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The natural-language comments and user-facing messages are presented only in Chinese, which effectively forces a specific language for installation guidance and errors. The file does not offer any user opt-in, alternative locale, or justification for restricting the skill to Chinese-language output.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The description is written as broad promotional copy and does not define clear activation boundaries, supported inputs, or limiting conditions. In agent ecosystems, this can cause the skill to be selected in overly broad contexts, increasing the chance it is invoked on unintended data-processing tasks and exposing users to unexpected file handling or workflow behavior.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The skill description is effectively Chinese-only and does not disclose a locale requirement or offer language choice. This can mislead routing or user understanding, causing the skill to be invoked for users who cannot read the description or constraints, which increases the risk of misuse or accidental execution in the wrong context.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The module docstring and user-facing description are entirely in Chinese, and the CLI help/messages throughout the file continue that assumption. This creates a language/locale policy concern because the skill presents a fixed language experience with no opt-in or alternative for users who may expect another language.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The code explicitly permits the premium scatter feature to continue when license verification infrastructure fails, despite a comment stating it should be restricted in production. This creates a fail-open authorization bypass: an attacker or normal user can access paid functionality by inducing license-manager failure, missing dependencies, or other exceptions.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
All user-facing instructional content in the file is presented in Chinese, and the document does not indicate that language selection is optional or that the skill is intentionally limited to a Chinese-speaking regional context. The policy for natural-language content requires avoiding forced language or locale constraints unless users are given a choice or the restriction is clearly justified.

Static analysis

No suspicious patterns detected.