Back to skill

Security audit

In Silico Perturbation Oracle

Security checks for vulnerabilities and agentic risk

Overview

The skill is a user-directed bioinformatics simulator, but it overstates production-grade foundation-model predictions and can produce wet-lab target guidance from placeholder random code.

Install only in an isolated environment, pin and audit dependencies first, and do not use this skill for real experimental, therapeutic, clinical, or business decisions unless the model integrations and validation claims are independently verified. Keep outputs confined to a workspace directory and treat any remote model/API use as sensitive biological data handling until the publisher documents it clearly.

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)

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Unpinned Third-Party Dependencies Create Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt:1-18` **Vulnerability Type**: Unpinned third-party dependencies **Risk Level**: Medium ### Vulnerable Code ```text anndata biopython dataclasses gseapy h5py matplotlib mygene numpy pandas plotly pyyaml scanpy scipy scvi-tools seaborn torch tqdm transformers ``` The installation instructions in `SKILL.md:66-74` also recommend additional unpinned packages: ```bash # Basic dependencies pip install torch transformers scanpy scvi-tools # Bioinformatics tools pip install gseapy enrichrpy # Model-specific dependencies pip install geneformer scgpt ``` ### Technical Analysis All declared dependencies lack exact version constraints and integrity hashes. Consequently, installation resolves whichever releases are current at that time rather than a previously reviewed dependency set. The documentation also instructs users to install model-specific packages that are not represented in `requirements.txt`. This creates a supply-chain exposure in which a compromised, malicious, or unexpectedly incompatible future release can be installed without any repository change. Python packages may execute code during installation and later during import with the privileges of the user running `pip` or the application. The broad dependency list also increases the attack surface. Several packages are not imported by the current implementation, meaning users may install unnecessary components with their own transitive dependency trees. ### Attack Path 1. An attacker compromises an existing dependency, one of its transitive dependencies, or a future package release. 2. The attacker publishes a malicious version under a package name allowed by the unpinned manifest or installation instructions. 3. A user follows `SKILL.md` or runs `pip install -r requirements.txt`. 4. The package resolver selects the malicious release because no reviewed version or hash is required. 5. Malicious installation hooks or imported ...[truncated 878 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct dependency to an exact, reviewed version, for example: ```text numpy==2.1.3 pandas==2.2.3 ``` 2. Generate and commit a lock file containing the complete transitive dependency graph. 3. Require package hashes during installation, such as through a hash-locked requirements file and: ```bash pip install --require-hashes -r requirements.lock ``` 4. Move all packages required by the documented installation process into one authoritative dependency manifest. 5. Remove packages that are not used by the current implementation. 6. Run dependency vulnerability and provenance checks in CI. 7. Install dependencies in an isolated, unprivileged virtual environment or container. 8. Review dependency updates before regenerating the lock file rather than accepting updates automatically. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:1036
Finding
Path Traversal and Arbitrary File Overwrite Through Unsanitized Result Prefix<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py:1036-1067` **Vulnerability Type**: Path traversal and arbitrary file overwrite **Risk Level**: Medium ### Vulnerable Code ```python def save(self, prefix: str = ""): """Save all results""" # Save DEG results deg_df = self.get_differential_expression() deg_path = self.output_dir / f"{prefix}deg_results.csv" deg_df.to_csv(deg_path, index=False) logger.info(f"DEG results saved to {deg_path}") # Save target scores score_df = self.score_targets() score_path = self.output_dir / f"{prefix}target_scores.csv" score_df.to_csv(score_path, index=False) logger.info(f"Target scores saved to {score_path}") # Save pathway enrichment results pathways = self.enrich_pathways() pathway_path = self.output_dir / f"{prefix}pathway_enrichment.json" # Convert to serializable format pathways_serializable = {} for db, results in pathways.items(): pathways_serializable[db] = [ { "pathway_name": r.pathway_name, "p_value": r.p_value, "enrichment_ratio": r.enrichment_ratio, "overlap_genes": r.overlap_genes, "database": r.database } for r in results ] with open(pathway_path, 'w') as f: json.dump(pathways_serializable, f, indent=2) ``` ### Technical Analysis The public `PerturbationResult.save()` API directly incorporates the caller-controlled `prefix` into three output paths without validating path separators, parent-directory components, or absolute paths. A prefix containing `../` can cause path resolution outside `self.output_dir`. A prefix beginning with an absolute path can also cause `pathlib.Path` joining behavior to discard the intended parent directory. The resulting paths are passed to `pandas.DataFrame.to_csv()` and `open(..., 'w')`, which create or truncate files using the ...[truncated 1750 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Restrict `prefix` to a filename-safe allowlist and reject directory separators: ```python import re if not re.fullmatch(r"[A-Za-z0-9_.-]*", prefix): raise ValueError("Invalid result filename prefix") ``` 2. Resolve every destination and verify that it remains beneath the resolved output directory: ```python output_root = self.output_dir.resolve() destination = (output_root / f"{prefix}deg_results.csv").resolve() if output_root not in destination.parents: raise ValueError("Output path escapes the configured directory") ``` 3. Apply the containment check separately to every generated output path. 4. Reject absolute paths, `..` components, null bytes, and both platform-specific path separators. 5. Create the output directory explicitly and use safe file-creation behavior where overwriting is not required. 6. Consider removing the path-like `prefix` parameter entirely and accepting only a validated logical run identifier. 7. Add tests covering absolute paths, nested traversal, mixed separators, symbolic links, and valid ordinary prefixes. 8. Run the application with a dedicated, least-privileged account whose writable directories are limited to the designated workspace. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (38)

Possible Typosquatting: 'scanpy' resembles popular package 'scrapy'

High
Category
Supply Chain
Confidence
70% confidence
Finding
Package name closely resembles a popular package, suggesting possible typosquatting. Attackers publish malicious packages with similar names to trick developers into installing them.

Intent-Code Divergence

High
Confidence
99% confidence
Finding
The top-level documentation markets the tool as using biological foundation models for gene knockout prediction, while the implementation uses placeholder random simulation. This mismatch is especially dangerous in a scientific decision-support context because it can mislead users into trusting outputs as model-derived evidence when they are not.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The implementation claims to perform foundation-model-based perturbation prediction, but the core logic is explicitly synthetic and random. In a bioinformatics skill that may drive experimental prioritization, this is dangerous because users could make research or therapeutic decisions based on fabricated outputs that appear scientifically grounded.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill documents executable scripts plus file read/write behavior, but it does not declare an explicit tool scope such as permissions or allowed-tools. That creates ambiguity around what the agent is authorized to access and increases the risk of over-broad filesystem actions, especially because results and inputs are path-based and the security checklist is only aspirational.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The skill acknowledges high-risk capabilities like network access and filesystem handling but does not clearly warn users that uploaded biological data, gene lists, cell-type metadata, or generated reports may be transmitted to external services or stored locally. In a bioinformatics context, such data can be sensitive or proprietary, so lack of transparent handling guidance can lead to unintended data exposure or compliance issues.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The skill extends beyond stated transcriptional-change prediction into therapeutic target ranking and wet-lab validation recommendations. That scope expansion increases risk because it converts unvalidated simulated outputs into downstream action guidance, potentially influencing real laboratory work under false assumptions of scientific validity.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The combinatorial knockout synergy feature materially expands the operational purpose beyond the manifest's stated single-knockout prediction. In this context, hidden capability expansion is risky because users may rely on unsupported combination-effect outputs that can further compound errors from the already simulated prediction pipeline.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
The comment on L002 is written in Chinese while the rest of the file's human-readable descriptions are primarily in English. This creates an implicit language constraint for maintainers or users reading the configuration, and there is no accompanying note indicating bilingual support, locale scope, or user opt-in.

Natural-Language Policy Violations

Low
Confidence
85% confidence
Finding
This YAML file includes natural-language comments in Chinese alongside English identifiers, which can impose a language expectation on maintainers or users without any stated opt-in or locale guidance. Under the language/locale policy rule, forcing or assuming a specific language in user-facing instructions or comments can be a policy concern when no choice is offered.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The file contains natural-language comments only in Chinese on L56-L57, which introduces a locale-specific instruction style without any documented opt-in, language choice, or region-specific justification. Under the policy criteria, forcing a specific language or locale in natural-language content is a policy concern even in configuration files.

Unpinned Dependencies

Low
Category
Supply Chain
Content
anndata
biopython
dataclasses
gseapy
Confidence
98% confidence
Finding
The dependency 'anndata' is unpinned, so builds may resolve to different versions over time, creating supply-chain unpredictability and making it difficult to reproduce or audit the environment. In an ML/bioinformatics skill with many transitive dependencies, this increases exposure to newly introduced vulnerable or breaking releases.

Unpinned Dependencies

Low
Category
Supply Chain
Content
anndata
biopython
dataclasses
gseapy
h5py
Confidence
99% confidence
Finding
The dependency 'biopython' is unpinned, which allows installation of arbitrary future or repository-resolved versions and prevents verification against known advisories. Because this skill processes biological data and may parse complex file formats, version drift can expose the environment to supply-chain and parser-related security risk.

Unverifiable Dependency: biopython has 2 known advisory(ies) (CVE-2025-68463 (Biopython is vulnerable to doctype XML external entity (XXE) injection through B); CVE-2025-68463 (Biopython is vulnerable to doctype XML external entity (XXE) injection through B)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
98% confidence
Finding
Because 'biopython' is unpinned and has known advisories, the manifest cannot establish whether deployed environments are safe or affected. This is especially relevant for a biology-focused skill that may parse structured bioinformatics data where parser flaws such as XXE can become reachable.

Unpinned Dependencies

Low
Category
Supply Chain
Content
anndata
biopython
dataclasses
gseapy
h5py
matplotlib
Confidence
94% confidence
Finding
The dependency 'dataclasses' is unpinned, which reduces build reproducibility and can cause inconsistent environments across installations. While lower risk than packages with a long advisory history, leaving it unpinned still weakens supply-chain control.

Unpinned Dependencies

Low
Category
Supply Chain
Content
anndata
biopython
dataclasses
gseapy
h5py
matplotlib
mygene
Confidence
97% confidence
Finding
The dependency 'gseapy' is unpinned, so installs are not deterministic and may silently pick up vulnerable or incompatible upstream releases. In scientific workflows, this can affect both security posture and result integrity.

Unpinned Dependencies

Low
Category
Supply Chain
Content
biopython
dataclasses
gseapy
h5py
matplotlib
mygene
numpy
Confidence
97% confidence
Finding
The dependency 'h5py' is unpinned, which can lead to inconsistent dependency resolution and unknown exposure to vulnerabilities in native/parsing code paths. Libraries handling HDF5 data can be sensitive because malformed files may trigger crashes or unsafe behavior in affected versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
dataclasses
gseapy
h5py
matplotlib
mygene
numpy
pandas
Confidence
95% confidence
Finding
The dependency 'matplotlib' is unpinned, creating non-reproducible installs and making security/compliance review harder. Although plotting libraries are often lower risk than deserializers or model loaders, unpinned versions still increase supply-chain uncertainty.

Unpinned Dependencies

Low
Category
Supply Chain
Content
gseapy
h5py
matplotlib
mygene
numpy
pandas
plotly
Confidence
96% confidence
Finding
The dependency 'mygene' is unpinned, which weakens dependency integrity and allows unnoticed changes in installed behavior or security posture. In a data-enrichment workflow that may contact external services, predictable versions are important for auditing and risk management.

Unpinned Dependencies

Low
Category
Supply Chain
Content
h5py
matplotlib
mygene
numpy
pandas
plotly
pyyaml
Confidence
99% confidence
Finding
The dependency 'numpy' is unpinned, so the environment may resolve to versions with known defects or advisories and cannot be reliably audited. Because this package is foundational and widely depended upon, version drift can affect a large portion of the runtime surface.

Unverifiable Dependency: numpy has 16 known advisory(ies) (CVE-2014-1859 (Numpy arbitrary file write via symlink attack); CVE-2021-41495 (NumPy NULL Pointer Dereference); CVE-2021-33430 (NumPy Buffer Overflow (Disputed)) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
97% confidence
Finding
Because 'numpy' is unpinned despite a history of advisories, the security status of installed environments is unverifiable. As a core scientific dependency used throughout the stack, uncertainty here propagates broadly and complicates patch management.

Unpinned Dependencies

Low
Category
Supply Chain
Content
matplotlib
mygene
numpy
pandas
plotly
pyyaml
scanpy
Confidence
99% confidence
Finding
The dependency 'pandas' is unpinned, which undermines reproducibility and makes it impossible to know whether installations are affected by known issues. Since data-processing libraries may handle untrusted tabular inputs and serialization features, deterministic versioning matters.

Unverifiable Dependency: pandas has 1 known advisory(ies) (CVE-2020-13091 (** DISPUTED ** pandas through 1.0.3 can unserialize and execute commands from an)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding
The manifest leaves 'pandas' unpinned even though known advisories exist, so it is impossible to determine whether the deployed version is affected. In data-centric workflows, uncertainty around serialization or parser-related vulnerabilities is undesirable.

Unpinned Dependencies

Low
Category
Supply Chain
Content
mygene
numpy
pandas
plotly
pyyaml
scanpy
scipy
Confidence
95% confidence
Finding
The dependency 'plotly' is unpinned, increasing supply-chain unpredictability and complicating security review. While not necessarily dangerous by itself, leaving it floating can introduce untested changes into the skill.

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
pandas
plotly
pyyaml
scanpy
scipy
scvi-tools
Confidence
99% confidence
Finding
The dependency 'pyyaml' is unpinned, which is more concerning because PyYAML has a history of unsafe deserialization issues in certain usage patterns and versions. In a skill that may consume configuration or model metadata, unresolved version drift can materially increase exploitability.

Unverifiable Dependency: pyyaml has 8 known advisory(ies) (CVE-2019-20477 (Deserialization of Untrusted Data in PyYAML); CVE-2020-1747 (Improper Input Validation in PyYAML); CVE-2020-14343 (Improper Input Validation in PyYAML) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
99% confidence
Finding
The manifest leaves 'pyyaml' unpinned despite multiple known deserialization-related advisories, making it impossible to verify whether the runtime is vulnerable. If this skill reads YAML configuration or metadata, exploitation could become substantially more dangerous than a generic package-versioning issue.

Static analysis

No suspicious patterns detected.