Back to skill

Security audit

Skill Graphify

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated graph-building purpose, but it automatically installs unpinned third-party Python code and can analyze/write outputs in arbitrary target folders.

Install only in an isolated virtual environment or sandbox, review/pin the graphifyy dependency first, and run it only on an explicit folder you are comfortable having indexed into graph.json and GRAPH_REPORT.md.

Vulnerability Patterns
  • 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
  • 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)

T08 · Insecure Dependencies

Warning
Location
graphify_wrapper.py:13
Finding
Unpinned Automatic Installation and Execution of a Third-Party Package## Vulnerability Details **File Location**: `graphify_wrapper.py`, lines 13 and 18–39 **Vulnerability Type**: Unpinned third-party dependency installation **Risk Level**: Medium ### Vulnerable Code ```python GRAPHIFY_PKG = "graphifyy" def _run(cmd, **kwargs): """Run a command, return CompletedProcess.""" return subprocess.run(cmd, capture_output=True, text=True, timeout=kwargs.pop("timeout", 120), **kwargs) def ensure_installed(): """Ensure graphify is installed, install if missing. Returns python path.""" # Try importing graphify r = _run([sys.executable, "-c", "import graphify"]) if r.returncode == 0: return sys.executable # Install print(f"Installing {GRAPHIFY_PKG}...") r = _run([sys.executable, "-m", "pip", "install", "-q", GRAPHIFY_PKG], timeout=120) if r.returncode != 0: print(f"Install failed: {r.stderr}") sys.exit(1) # Verify r = _run([sys.executable, "-c", "import graphify"]) if r.returncode != 0: print("Install succeeded but import failed") sys.exit(1) return sys.executable ``` The automatic installation is also presented as expected usage in `SKILL.md`, lines 20–24 and 96–98: ```markdown ### Step 1 — Ensure graphify is installed ```bash python graphify_wrapper.py ensure-installed ``` ## Dependencies - Python 3.10+ - `graphifyy` (pip) — automatically installed by wrapper ``` ### Technical Analysis The wrapper installs `graphifyy` from the process's active pip index without an exact version constraint, cryptographic hash verification, or a dependency lock file. Consequently, the effective dependency code can change after the Skill itself has been audited. The risk also depends on the environment's pip configuration. A compromised package release, compromised package index, or attacker-controlled alternate index could cause pip to retrieve and install unauthorized code. After installation, the wrapper imports and executes the dependency throu ...[truncated 1707 chars]
Remediation
## Remediation Suggestions 1. Pin `graphifyy` to a specifically reviewed version rather than installing an unconstrained latest release: ```python GRAPHIFY_PKG = "graphifyy==<reviewed-version>" ``` 2. Maintain a locked requirements file containing hashes and install it with hash enforcement: ```bash python -m pip install --require-hashes -r requirements.lock ``` 3. Pin and hash all transitive dependencies, not only the direct package. 4. Explicitly use a trusted package index and prevent unintended fallback to additional indexes. Review environment-level pip configuration before installation. 5. Avoid automatic dependency installation during normal Skill execution. Instead, fail safely with clear, separately documented installation instructions that require explicit user approval. 6. Install the dependency in a dedicated virtual environment or other sandbox rather than modifying the Agent's active Python environment. 7. Execute graph processing with least privilege and restrict its filesystem, credential, and network access where the runtime supports sandboxing. 8. Verify the pinned release's provenance and integrity before updating the lock file. Re-audit package updates before deployment.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (9)

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README states that the wrapper auto-installs a pip package, but it does not warn users that running the skill may modify the local Python environment or fetch code from an external package source. In an agent-executed context, silent dependency installation increases supply-chain and environment-integrity risk because the agent may perform networked package installation without explicit user approval.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill clearly instructs use of shell commands, package installation, and writing outputs into the target project, yet it declares no explicit tool scope or permission boundaries. That creates an authorization gap where an agent may invoke powerful file and shell capabilities without clear limits, increasing the chance of over-broad access, unintended modification, or unsafe execution in sensitive directories.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The activation scope is overly broad: phrases like turning "any folder" into a graph and generic usage triggers provide no exclusions for sensitive repositories, home directories, secrets-containing paths, or very large datasets. In an agent setting, vague activation criteria can cause the skill to be applied in contexts the user did not intend, leading to unnecessary scanning, exposure of confidential structure, or excessive processing of sensitive files.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The instructions direct auto-installation of a package and creation of multiple output artifacts under the target project, but they do not disclose those side effects or require consent. This is dangerous because package installation executes supply-chain risk and environment changes, while writing into the analyzed project can alter repositories, contaminate worktrees, or expose generated summaries of sensitive content.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def _run(cmd, **kwargs):
    """Run a command, return CompletedProcess."""
    return subprocess.run(cmd, capture_output=True, text=True, timeout=kwargs.pop("timeout", 120), **kwargs)


def ensure_installed():
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The wrapper silently installs a package from PyPI at runtime, which expands a local file-processing skill into remote code acquisition and execution. This creates supply-chain risk: a typo-squatted, compromised, or unexpectedly updated package could run arbitrary code in the user's environment, especially because installation occurs automatically when import fails.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
Automatically invoking pip install without prior user confirmation causes unexpected network access and executes package installation logic in the current environment. In skill context, this is more dangerous because the skill is described as a local graphing wrapper, so users may not anticipate dependency fetching or the attendant supply-chain and environment-modification risks.

Description-Behavior Mismatch

Low
Confidence
75% confidence
Finding
The manifest says the skill turns a folder into a queryable knowledge graph, which implies analysis, but this implementation creates an output directory and writes intermediate and final artifacts such as .graphify_detect.json, .graphify_ast.json, graph.json, and GRAPH_REPORT.md. While some output writing is expected, the extent of generated artifacts is broader than the sparse manifest description.

Intent-Code Divergence

Low
Confidence
95% confidence
Finding
The code prints that output includes 'graph.html — interactive visualization', but no earlier logic in this file creates graph.html or invokes any export step that would generate it. This is an active contradiction between user-facing documentation/output text and actual behavior.

Static analysis

No suspicious patterns detected.