Back to skill

Security audit

bubble_plot

Security checks for vulnerabilities and agentic risk

Overview

The skill appears intended to generate gene-expression bubble plots, but its script can write output files outside the chosen output folder and its setup advice modifies the system Python environment.

Review before installing. Use the skill only with trusted input files unless filenames are sanitized, run it in a virtual environment instead of following the system Python install command, and choose an output directory where accidental overwrites would not damage important files.

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

Error
Location
bubble_plot.py:226
Finding

Path Traversal Through Untrusted Output Filenames

Content
View full analysis

Vulnerability Details

File Location: bubble_plot.py, lines 226–236
Vulnerability Type: Path traversal and arbitrary file overwrite
Risk Level: High

python
            base = f"{gene}_dotplot"
            if label:
                base += f"_{label}"

            png_path = os.path.join(args.outdir, f"{base}.png")
            pdf_path = os.path.join(args.outdir, f"{base}.pdf")

            fig.savefig(png_path, dpi=args.dpi, bbox_inches='tight', facecolor='white')
            fig.savefig(pdf_path, bbox_inches='tight', facecolor='white')
            plt.close(fig)
            files_written.extend([png_path, pdf_path])

Technical Analysis

The output filename is built directly from gene and label without filename sanitization or path-containment validation.

The gene value originates either from command-line arguments or from column names in an untrusted CSV/TSV file. The label value originates from the tissue column in that file. Both can therefore contain absolute paths, path separators, or parent-directory components such as ../.

Passing the constructed value to os.path.join() does not enforce containment within args.outdir. In particular:

  • An absolute gene value causes os.path.join() to discard the output-directory prefix.
  • Relative traversal components can resolve outside the output directory.
  • matplotlib.figure.Figure.savefig() overwrites an existing writable destination without requiring confirmation.

Exploitation requires the target parent directory to exist and the process to have write permission. The generated content remains a PNG or PDF plot, which limits the attacker to files using those appended extensions, but it does not prevent unauthorized creation or replacement of such files.

Attack Path

  1. An attacker supplies a CSV/TSV expression file containing a numeric gene column with a crafted name such as ../../shared/report, or persuades the o ...[truncated 1138 chars]
Remediation
View remediation

Remediation Suggestions

  • Convert every untrusted filename component to a safe basename using a strict allowlist, such as ASCII letters, digits, periods, underscores, and hyphens.
  • Reject absolute paths, . and .. components, directory separators, null bytes, and platform-specific path separators.
  • Resolve the output directory and every candidate destination with pathlib.Path.resolve(), then verify that the destination remains beneath the resolved output directory.
  • Generate internal identifiers for output filenames instead of using raw dataset labels. Maintain a separate mapping from identifiers to display labels if necessary.
  • Avoid silently overwriting existing files. Use exclusive creation, generate a unique filename, or require explicit overwrite consent.
  • Apply length limits to filename components to prevent filesystem errors and denial-of-service conditions.

Example containment check:

python
from pathlib import Path
import re

def safe_component(value):
    value = re.sub(r"[^A-Za-z0-9._-]+", "_", str(value))
    value = value.strip("._")
    if not value:
        raise ValueError("Unsafe or empty filename component")
    return value[:128]

output_root = Path(args.outdir).resolve()
base = safe_component(gene) + "_dotplot"
if label:
    base += "_" + safe_component(label)

png_path = (output_root / f"{base}.png").resolve()
pdf_path = (output_root / f"{base}.pdf").resolve()

if output_root not in png_path.parents or output_root not in pdf_path.parents:
    raise ValueError("Output path escapes the configured directory")

T08 · Insecure Dependencies

Warning
Location
SKILL.md:31
Finding

Unpinned Dependency Installation Into the System Python Environment

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, line 31
Vulnerability Type: Unsafe and non-reproducible dependency installation
Risk Level: Medium

bash
pip3 install --break-system-packages pandas matplotlib

Technical Analysis

The Skill documentation directs the Agent to install unpinned versions of pandas and matplotlib into the system Python environment. The --break-system-packages option explicitly bypasses protections for externally managed Python installations.

Because no versions or package hashes are specified, the installed artifacts can change over time and may introduce incompatible, compromised, or insufficiently reviewed direct and transitive dependencies. Modifying the system environment also creates dependency conflicts and expands the effect beyond this individual Skill.

The package names shown are established packages rather than apparent typosquatting names, and the instruction does not specify an untrusted package index. The risk arises from mutable dependency resolution, transitive supply-chain exposure, and bypassing environment-isolation controls.

Attack Path

  1. The Agent determines that pandas or matplotlib is unavailable.
  2. Following the Skill instructions, it executes the documented pip3 install --break-system-packages command.
  3. pip resolves the latest available direct and transitive package versions at execution time.
  4. Those packages are installed into or over the system-managed Python environment.
  5. A compromised dependency release, unsafe transitive update, or incompatible package can then execute installation or runtime behavior with the privileges of the Agent process.
  6. The modified environment can affect this Skill and other Python applications sharing the same interpreter.

Impact Assessment

A compromised dependency could execute code with the same filesystem, network, and process privileges as the Agent performing the installation ...[truncated 409 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove --break-system-packages.
  • Create and use a dedicated virtual environment for the Skill.
  • Pin reviewed direct and transitive dependency versions in a lock file.
  • Require package hashes, for example through pip install --require-hashes -r requirements.txt.
  • Use a trusted, explicitly configured package index or an internally reviewed package mirror.
  • Perform dependency vulnerability and integrity scanning before releases.
  • Prefer a reproducible setup such as:
bash
python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install --require-hashes -r requirements.txt
  • Document supported Python and dependency versions so users do not need to modify the system interpreter.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (1)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest description and title are entirely in Chinese, and the operational guidance throughout the file is also Chinese-only. This creates a natural-language locale constraint without any user opt-in or justification that the skill is intended only for Chinese-speaking users or a China-specific context.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.