Back to skill

Security audit

Epigrass Creator

Security checks for vulnerabilities and agentic risk

Overview

This skill is a model-building wizard with some documentation and input-validation weaknesses, but no hidden execution, data theft, persistence, or purpose-mismatched behavior was found.

Install in an isolated environment, prefer pinned dependency versions, use a dedicated empty output directory, and review generated model.epg and CSV files before running epirunner, especially if any model inputs or GeoPackage files came from someone else.

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
README.md:8
Finding

Unpinned Third-Party Package Installation Creates a Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: README.md:8, README.md:101-103; SKILL.md:52, SKILL.md:77; examples/geopackage_example.md:118
Vulnerability Type: Unpinned and unverifiable third-party dependencies
Risk Level: Medium

Vulnerable Code Snippets

README.md:8:

bash
npx clawhub install epigrass-creator

README.md:101-103:

bash
pip install geopandas  # Recommended
# or
pip install fiona      # Lightweight alternative

SKILL.md:52:

text
Requirements: `pip install geopandas` (or fiona as fallback)

SKILL.md:77:

text
- epigrass (`pip install epigrass`)

examples/geopackage_example.md:118:

bash
pip install geopandas

Technical Analysis

The documentation instructs users to install and potentially execute third-party packages using mutable package names. It does not pin reviewed versions, verify package hashes, provide a lockfile, or explicitly constrain downloads to an authenticated trusted package index.

The npx command is particularly sensitive because it can download and execute package code in one operation. Python package installation can also execute build-system code or install packages that execute code when imported. The application subsequently imports geopandas or fiona at runtime in wizard.py:29-43.

There is no evidence in the audited project that the named packages are currently malicious. The vulnerability is the absence of controls that ensure users receive the same reviewed dependency versions over time.

Attack Path

  1. An attacker compromises a referenced package, its publisher account, or the package registry delivery path.
  2. Alternatively, a future malicious release is published under one of the mutable package names.
  3. A user follows the documented npx or pip install command.
  4. The package manager retrieves the attacker-controlled release because no version or hash is fixed.

...[truncated 716 chars]

Remediation
View remediation

Remediation Suggestions

  1. Publish a reviewed dependency manifest with exact versions rather than mutable package names.
  2. Use a hash-locked requirements file and recommend installation with:
    bash
    python3 -m pip install --require-hashes -r requirements.txt
    
  3. Pin the clawhub installer to a reviewed version instead of relying on the latest package selected by npx.
  4. Explicitly specify the expected trusted registry and verified package publisher.
  5. Use a lockfile generated from reviewed dependency versions, including transitive dependencies where practical.
  6. Document installation inside an isolated virtual environment without administrator privileges.
  7. Add automated dependency integrity, provenance, and vulnerability checks to the release process.

T09 · Insecure Skill Coding Practices

Warning
Location
epigrass_wizard.py:302
Finding

User-Controlled Identifiers and Strings Are Interpolated into an Executable Epigrass Script

Content
View full analysis

Vulnerability Details

File Location: epigrass_wizard.py:302-329, epigrass_wizard.py:398-411; wizard.py:211-221, wizard.py:267-282
Vulnerability Type: Generated-script injection
Risk Level: Medium

Vulnerable Code Snippets

epigrass_wizard.py:302-329 accepts arbitrary setting names and string values:

python
def add_simulation_setting(self, setting: str) -> bool:
    """Add simulation setting"""
    if setting.lower() == 'done':
        return True
        
    try:
        if '=' in setting:
            key, value = setting.split('=', 1)
            key = key.strip()
            value = value.strip()
            
            # Try to convert to appropriate type
            if value.lower() in ('yes', 'true'):
                value = True
            elif value.lower() in ('no', 'false'):
                value = False
            else:
                try:
                    value = int(value)
                except ValueError:
                    try:
                        value = float(value)
                    except ValueError:
                        pass
            
            self.model_spec['simulation'][key] = value
            return True
    except ValueError:
        pass
    
    return False

epigrass_wizard.py:398-411 inserts those values directly into generated model syntax:

python
# Add model-specific parameters
for key, value in self.model_spec['parameters'].items():
    script += f"{key} = {value}\n"

# Add simulation settings
script += "\n# Simulation settings\n"
for key, value in self.model_spec['simulation'].items():
    if isinstance(value, str):
        script += f"{key} = '{value}'\n"
    else:
        script += f"{key} = {value}\n"

return script

The alternate implementation in wizard.py:211-221 also accepts arbitrary parameter identifiers:

python
while True:
    li
...[truncated 3506 chars]
Remediation
View remediation

Remediation Suggestions

  1. Define an explicit allowlist of supported parameter and simulation-setting names.
  2. For extensible identifiers, require a strict identifier format such as:
    text
    ^[A-Za-z_][A-Za-z0-9_]*$
    
  3. Reject quote characters, control characters, line separators, statement delimiters, comments, and other syntax-significant content where it is not explicitly required.
  4. Do not manually surround untrusted strings with quotes. Use a serialization mechanism defined by the Epigrass file format. If Python-compatible literals are explicitly required, use a safe serializer such as json.dumps() and verify compatibility with the downstream parser.
  5. Prefer generating a structured, non-executable configuration format rather than source-like model syntax.
  6. Validate all values against expected types, finite numeric ranges, and semantic constraints before file generation.
  7. Add tests using malicious identifiers and values containing quotes, delimiters, comments, and control characters.
  8. Warn users that generated files should be reviewed before execution, especially when any input originated from an untrusted party.
  9. Apply the same validation and serialization controls consistently in both epigrass_wizard.py and wizard.py.
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • 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
Findings (13)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill advertises capabilities such as GeoPackage import, network construction, and complete step-by-step model generation that static analysis indicates are not actually implemented. This is dangerous because users may rely on nonexistent data-import or model-building steps, producing incomplete or incorrect epidemiological models and potentially making downstream public-health decisions based on false assumptions about what the tool validated or generated.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · epigrass_wizard.py (reported line 87)May include surrounding context.

python
**Enter your choice (1-6):**"""
        
        return prompt
    
    def set_model_type(self, choice: str) -> bool:
        """Set model type based on user choice"""

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · epigrass_wizard.py (reported line 221)May include surrounding context.

python
**Enter your choice (1-6):**"""
        
        return prompt
    
    def set_model_type(self, choice: str) -> bool:
        """Set model type based on user choice"""

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The changelog explicitly says the skill removed misleading 'auto-fetch' language and clarified city entry as manual coordinate entry, but the later usage example still presents option 1 as 'Enter cities (auto-fetch data)'. This is an active contradiction within the documentation that misrepresents the skill's actual intended behavior.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file is in scope for vague-trigger review, and the example option "Enter cities (auto-fetch data)" is broad enough to overlap with ordinary user requests about cities without clarifying when the skill should or should not activate. The changelog provides no negative examples or trigger-scope constraints to narrow invocation behavior.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding

The README instructs users to run npx clawhub install epigrass-creator without pinning a specific version of the package. This can cause users to execute whatever package version is current at install time, increasing supply-chain risk if a malicious or compromised release is published or if dependency resolution changes unexpectedly.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The module docstring states that the wizard supports built-in and custom models, and the prompt collects custom compartments and transitions. However, the only parameter ingestion implemented is simple key=value parsing, with no parser or storage logic for custom compartments, transitions, or initial conditions, so the claimed custom-model behavior is not actually implemented.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest describes support for importing GeoPackage spatial data and building geographic networks, but the code in this file only accepts manually entered sites or synthetic grids and never parses GeoPackage files. It also prompts for edge definitions but provides no code to ingest or generate edges, so the implemented behavior is materially narrower than the advertised capabilities.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The site-entry prompt explicitly tells users that providing Brazilian city names will cause the system to fetch coordinates and populations. In reality, add_site only handles comma-separated manual records or a grid spec and contains no lookup, geocoding, or data retrieval logic, so the prompt directly contradicts actual behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
71% confidence
Finding

This markdown section describes importing real-world spatial datasets and handling thousands of sites, which can affect user data and system processing, but it does not include any warning about validating input files, reviewing mapped columns, or potential impacts of bulk import. For markdown files, omissions of warnings about behaviors affecting user data or system integrity are in scope.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The wizard writes fixed filenames into a caller-controlled directory using overwrite-capable opens without warning or existence checks. In a skill context, this can clobber preexisting files in the target directory and cause unintended data loss, especially if integrated into larger automated workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code accepts an output directory from the user and then creates directories and writes multiple files into that location. Although the writes are part of the wizard's purpose, there is no explicit disclosure that existing files such as model.epg, sites.csv, edges.csv, or model_spec.json may be created or overwritten in the chosen directory.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.