Back to skill

Security audit

Survival Analysis (KM)

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent survival-analysis tool, but it needs Review because it installs mutable unpinned dependencies and can write output files to any caller-supplied writable directory without enforcing the claimed workspace boundary.

Install and run this only in an isolated environment with a least-privileged account. Pin or lock dependencies before use, and direct --output to a fresh project-local directory so existing files named km_curve.png, km_curve.pdf, report.txt, survival_stats.csv, logrank_test.csv, logrank_pairwise.csv, or hazard_ratios.csv are not overwritten. Treat clinical or biomedical input data as sensitive and review statistical results with appropriate expertise.

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 a Mutable Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-5; installation instruction at SKILL.md:165-168
Vulnerability Type: Unpinned third-party dependencies
Risk Level: Medium

Vulnerable Code

requirements.txt:1-5:

text
lifelines
matplotlib
numpy
pandas
seaborn

SKILL.md:165-168:

bash
# Python dependencies
pip install -r requirements.txt

Technical Analysis

All dependencies are specified without exact versions or package integrity hashes. Consequently, the documented installation command resolves whichever eligible package versions are available from the configured package index at installation time.

This makes the installed code mutable after the Skill has been reviewed. A newly released, compromised, or otherwise incompatible dependency can be selected without any change to the audited repository. Python packages may execute code during installation and are imported by scripts/main.py, so compromised dependency code could also execute when the Skill runs.

The project does not exhibit typosquatting or explicitly configure an untrusted package index. Exploitation therefore depends on compromise of a dependency release, package index, or dependency-resolution environment.

Attack Path

  1. An attacker compromises an eligible release of one of the listed packages, its distribution channel, or the package-resolution environment.
  2. A user follows the documented pip install -r requirements.txt instruction.
  3. pip resolves the unpinned dependency to attacker-controlled or compromised package content.
  4. Malicious package code executes during installation or when imported by scripts/main.py.
  5. The payload operates with the permissions of the user or service account performing the installation or analysis.

Impact Assessment

Successful exploitation could provide arbitrary Python code execution with the privileges of the account installing or ru ...[truncated 282 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin every direct dependency to a reviewed exact version, for example package==x.y.z.
  2. Generate and commit a fully resolved lock file that includes transitive dependencies.
  3. Require package hashes during installation, such as through a hash-locked requirements file and pip install --require-hashes.
  4. Retrieve packages only from an approved package index over authenticated TLS; disable unintended extra indexes.
  5. Add automated dependency vulnerability and provenance scanning to the release process.
  6. Review and deliberately update the lock file rather than allowing installation-time version selection.
  7. Perform installation and execution in an isolated environment under a least-privileged account.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:392
Finding

Caller-Controlled Output Directory Allows Unrestricted File Overwrite

Content
View full analysis

Vulnerability Details

File Location: scripts/main.py:271-272, scripts/main.py:372-373, and scripts/main.py:392-466
Vulnerability Type: Unrestricted output path and unsafe overwrite behavior
Risk Level: Medium

Vulnerable Code

scripts/main.py:392-393:

python
# Create output directory
os.makedirs(args.output, exist_ok=True)

scripts/main.py:271-272:

python
if output_dir:
    plt.savefig(os.path.join(output_dir, 'km_curve.png'), dpi=300, bbox_inches='tight')
    plt.savefig(os.path.join(output_dir, 'km_curve.pdf'), bbox_inches='tight')

scripts/main.py:372-373:

python
with open(os.path.join(output_dir, 'report.txt'), 'w') as f:
    f.write(report_text)

scripts/main.py:444-466:

python
if args.group and 'group_stats' in survival_stats:
    survival_stats['group_stats'].to_csv(
        os.path.join(args.output, 'survival_stats.csv'), index=False
    )

if logrank_result:
    logrank_df = pd.DataFrame([{
        'test_type': logrank_result['test_type'],
        'test_statistic': logrank_result['test_statistic'],
        'p_value': logrank_result['p_value'],
        'significant': logrank_result['significant']
    }])
    logrank_df.to_csv(os.path.join(args.output, 'logrank_test.csv'), index=False)

    if 'pairwise' in logrank_result:
        logrank_result['pairwise'].to_csv(
            os.path.join(args.output, 'logrank_pairwise.csv'), index=False
        )

if hr_result:
    hr_result['hazard_ratios'].to_csv(
        os.path.join(args.output, 'hazard_ratios.csv'), index=False
    )

Technical Analysis

The --output argument is entirely caller-controlled. The program creates that path without resolving it against an approved workspace root, checking whether it traverses outside that root, or rejecting symbolic links. It then writes several predictable filenames using APIs that replace or truncate existing ...[truncated 1823 chars]

Remediation
View remediation

Remediation Suggestions

  1. Define an approved workspace output root and resolve the requested path with Path.resolve().
  2. Verify that the resolved destination is the approved root or one of its descendants before creating or writing files.
  3. Reject absolute paths, traversal outside the workspace, and destination components that are symbolic links.
  4. Open output files using exclusive-creation semantics where overwriting is unnecessary, or require explicit confirmation through an --overwrite option.
  5. Check each destination immediately before writing to reduce symlink race exposure.
  6. Create output directories with restrictive permissions and run the Skill under a least-privileged account.
  7. For stronger isolation, write into a newly created per-run directory beneath the approved workspace and return that directory to the caller.
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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (9)

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding

Suspicious Unicode normalization or mixed-script content

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger description is broad enough to match generic requests about survival analysis, Kaplan-Meier plots, and survival statistics, which can cause the skill to activate in more situations than intended. Over-broad triggering is dangerous because it can route unrelated or sensitive analytical requests into local script execution and file-processing flows without sufficient user intent confirmation, increasing the chance of misuse or accidental data exposure.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency 'lifelines' is unpinned, so builds may resolve to different versions over time. This creates supply-chain and reproducibility risk because a newly released or compromised version could be installed without review, though the file itself does not indicate active exploitation.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
lifelines
matplotlib
numpy
pandas

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency 'matplotlib' is unpinned, allowing installation of unpredictable versions across environments. While common in early-stage projects, this weakens supply-chain integrity and may introduce breaking changes or vulnerable releases unexpectedly.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
lifelines
matplotlib
numpy
pandas
seaborn

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
99% confidence
Finding

The dependency 'numpy' is unpinned, which is more concerning because the package has multiple historical advisories and the actual installed version cannot be determined from this manifest. An environment resolving to an affected release could inherit known flaws or unexpected behavior.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
lifelines
matplotlib
numpy
pandas
seaborn

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
95% confidence
Finding

Because 'numpy' is not version-pinned, it is impossible to verify whether the resolved installation includes a release affected by known advisories. This uncertainty is dangerous in dependency manifests because vulnerable versions may be silently installed depending on time and environment.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
99% confidence
Finding

The dependency 'pandas' is unpinned, so the package manager may install different versions over time, including releases with known or disputed security issues. This is a real supply-chain hygiene weakness even if no direct exploit path is shown in the skill itself.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
lifelines
matplotlib
numpy
pandas
seaborn

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
91% confidence
Finding

Because 'pandas' is not version-pinned, the manifest cannot demonstrate whether the environment will install a safe or affected version relative to the cited advisory. Although the cited issue may be disputed and often depends on unsafe deserialization usage, the unverifiable dependency state is still a real security weakness.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency 'seaborn' is unpinned, which reduces reproducibility and increases exposure to accidental uptake of problematic future releases. In this analytics skill, the risk is mostly supply-chain hygiene rather than an immediate direct exploit.

Content

Scanner excerpt · requirements.txt (reported line 5)May include surrounding context.

text
matplotlib
numpy
pandas
seaborn

Static analysis

No suspicious patterns detected.