Back to skill

Security audit

Clinical Data Cleaner

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local clinical-data cleaning skill, but it needs review because it can alter sensitive trial spreadsheets without formula-safety protections and installs unpinned Python packages.

Review this before using it on real trial data. Pin and review dependencies, run it in an isolated environment, preserve raw source files, avoid overwriting inputs, and add spreadsheet formula neutralization or treat generated CSV/Excel files as potentially unsafe when opened in spreadsheet software.

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

Warning
Location
scripts/main.py:399
Finding
Spreadsheet Formula Injection in Exported Clinical Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 108-117 and 399-406 **Vulnerability Type**: Untrusted spreadsheet content exported without formula neutralization **Risk Level**: Medium ### Vulnerable Code ```python def load_data(self, input_path: str) -> pd.DataFrame: """Load data from CSV or Excel file.""" path = Path(input_path) if not path.exists(): raise FileNotFoundError(f"Input file not found: {input_path}") if path.suffix.lower() == '.csv': return pd.read_csv(input_path) elif path.suffix.lower() in ['.xlsx', '.xls']: return pd.read_excel(input_path) ``` ```python # Save output output_path = Path(args.output) if output_path.suffix.lower() == '.csv': df_cleaned.to_csv(args.output, index=False) elif output_path.suffix.lower() in ['.xlsx', '.xls']: df_cleaned.to_excel(args.output, index=False) else: # Default to CSV df_cleaned.to_csv(args.output, index=False) ``` ### Technical Analysis The application accepts text fields from CSV or Excel files and writes them back to spreadsheet-compatible output without validating or neutralizing formula-prefixed values. Values beginning with characters such as `=`, `+`, `-`, or `@` may be interpreted as formulas by spreadsheet software. An attacker able to influence an input field—such as a subject identifier, study identifier, race value, test code, or another textual column—can insert a formula payload that survives the cleaning process. The Python process itself does not execute the formula. Exploitation occurs when a reviewer subsequently opens the generated CSV or Excel file in spreadsheet software with formula evaluation enabled. ### Attack Path 1. An attacker or compromised upstream data source inserts a formula-prefixed string into a textual clinical-data field. 2. The application loads the value through `pandas.read_csv()` or `pandas.read_excel()`. 3. The cleaning pipeline preserves the malicious text because ...[truncated 1220 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Before spreadsheet-compatible export, inspect every textual cell for leading formula characters such as `=`, `+`, `-`, and `@`. 2. Neutralize suspicious values using an explicit and documented policy, such as prefixing them with an apostrophe where appropriate. 3. Account for leading whitespace, tabs, carriage returns, and other characters that spreadsheet software may ignore before formula evaluation. 4. Preserve the original value in a protected audit record if regulatory traceability requires exact source-value retention. 5. Distinguish between raw archival exports and analyst-facing safe exports. 6. Add automated tests covering malicious values such as: - `=HYPERLINK(...)` - `+SUM(1,1)` - `@SUM(1,1)` - Formula strings preceded by spaces, tabs, or carriage returns 7. Warn users that output derived from untrusted inputs must not be opened with automatic formula evaluation enabled. 8. For Excel output, configure the writer to prevent string-to-formula conversion where the selected engine supports that option. ]]>

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Unpinned Third-Party Dependencies Permit Uncontrolled Package Resolution<![CDATA[ ## Vulnerability Details **File Location**: `requirements.txt`, lines 1-3; `scripts/requirements.txt`, lines 1-3 **Vulnerability Type**: Unpinned third-party dependencies **Risk Level**: Low ### Vulnerable Code ```text numpy pandas scipy ``` The same unpinned dependency declarations appear in both dependency manifests. ### Technical Analysis The project specifies package names without fixed versions or integrity hashes. Consequently, separate installations can resolve to different package releases depending on installation date, package-index state, platform, and resolver behavior. Although the package names are established and no malicious dependency was observed in the audited project, unconstrained dependency resolution weakens reproducibility and supply-chain control. A future compromised, vulnerable, or behaviorally incompatible release could be installed without any project change or explicit review. These packages are imported directly by `scripts/main.py`, so dependency initialization code executes when the clinical-data cleaner starts. ### Attack Path 1. A user or deployment process installs the dependencies from a configured Python package index. 2. Because no versions or hashes are fixed, the resolver selects whatever releases currently satisfy the unconstrained package names. 3. A compromised package-index account, unsafe mirror, altered release, or newly vulnerable package version becomes eligible for installation. 4. The package is installed without a lockfile or hash-based integrity verification detecting the change. 5. When `scripts/main.py` imports the dependency, its Python initialization code executes. 6. Malicious dependency code would run with the filesystem, data, and network permissions of the user operating the Skill. ### Impact Assessment Successful supply-chain exploitation could execute arbitrary Python code with the privileges of the installing or executing user. The reachable scope may include: - Clinical input ...[truncated 467 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every direct dependency to a reviewed version in both dependency manifests. 2. Generate a lockfile containing resolved transitive dependency versions. 3. Use hash-verified installation, such as pip requirements containing `--hash` entries and installation with `--require-hashes`. 4. Remove the duplicate dependency manifest or generate both manifests from one authoritative source to prevent configuration drift. 5. Install packages only from a trusted, explicitly configured package index. 6. Review dependency updates through a controlled change-management process. 7. Run vulnerability and license scanning against the complete resolved dependency graph. 8. Test updates against representative clinical datasets before deployment. 9. Use an isolated virtual environment or container with least-privilege filesystem and network access. ]]>
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (15)

Ae1

High
Category
analysis-evasion
Content
python scripts/main.py \
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
python scripts/main.py \
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The natural-language config value "text_case": "upper" imposes a formatting/language convention across all text values. Under the policy rule for language or locale constraints, this is a natural-language policy concern because it forces a specific representation without any visible user choice or documented justification in this file.

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
pandas
scipy
Confidence
98% confidence
Finding
The dependency list uses an unpinned package name for numpy, so installs are not reproducible and may resolve to a vulnerable or incompatible release. In a clinical-data processing skill, this increases supply-chain and reliability risk because the exact package version used for regulated data handling cannot be verified or audited.

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
88% confidence
Finding
Numpy has known advisories, and because no version is pinned, it is impossible to determine whether deployments are affected. This is dangerous because the project may silently install a vulnerable release, and in a compliance-oriented clinical workflow that lack of verifiability weakens both security assurance and audit readiness.

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
pandas
scipy
Confidence
98% confidence
Finding
The pandas dependency is unpinned, which allows different environments to install different versions with different security and behavior characteristics. For clinical trial data cleaning and submission preparation, that undermines reproducibility, validation, and auditability, making any downstream vulnerable release harder to detect and control.

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
86% confidence
Finding
Pandas has at least one known advisory, but the manifest does not specify a version, so the actual exposure cannot be assessed. In a skill handling clinical datasets, unverifiable dependency state is a meaningful security and governance issue because unsafe deserialization or similar defects could become reachable through surrounding code.

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
pandas
scipy
Confidence
98% confidence
Finding
The scipy requirement is also unpinned, so package resolution may pull an unexpected version, including one with known defects or advisories. While this is not an exploit by itself, it creates avoidable supply-chain uncertainty in a sensitive clinical-data context where exact software provenance matters.

Unverifiable Dependency: scipy has 4 known advisory(ies) (CVE-2013-4251 (SciPy creates insecure temporary directories); CVE-2013-4251 (The scipy.weave component in SciPy before 0.12.1 creates insecure temporary dire); CVE-2023-25399 (A refcounting issue which leads to potential memory leak was discovered in scipy) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding
Scipy has known advisories, and the absence of version pinning means the environment could resolve to an affected release without visibility. Even if no vulnerable path is currently known to be exercised, the inability to verify installed versions is itself a security and compliance weakness for regulated clinical data processing.

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
pandas
scipy
Confidence
98% confidence
Finding
The dependency list uses an unpinned package name for numpy, so builds may resolve to different versions over time. This weakens reproducibility and can unintentionally introduce a vulnerable or incompatible release into a clinical-data processing environment, especially problematic for regulated workflows that require consistency and auditability.

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
93% confidence
Finding
Numpy has known advisories, but the manifest does not specify a version, so there is no way to verify whether deployment will use a safe or affected release. The combination of a known vulnerable package history and unpinned installation leaves the environment exposed to accidental installation of a vulnerable version.

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
pandas
scipy
Confidence
98% confidence
Finding
The pandas dependency is not version-pinned, which allows future installations to pull different releases without review. In a clinical trial data-cleaning skill, this creates supply-chain and reproducibility risk because behavior or security posture may change between installs, undermining reliable regulated data processing.

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
90% confidence
Finding
Pandas has at least one reported advisory, and because the requirement is unpinned, the installed version cannot be verified as safe. This creates avoidable supply-chain uncertainty and can expose data-processing systems to known package flaws if an affected release is resolved.

Unpinned Dependencies

Low
Category
Supply Chain
Content
numpy
pandas
scipy
Confidence
98% confidence
Finding
The scipy dependency is unpinned, so installation may fetch an unexpected version with different security or runtime characteristics. This is dangerous in regulated data pipelines because it reduces reproducibility and can silently introduce vulnerable code or processing differences into submission-related workflows.

Unverifiable Dependency: scipy has 4 known advisory(ies) (CVE-2013-4251 (SciPy creates insecure temporary directories); CVE-2013-4251 (The scipy.weave component in SciPy before 0.12.1 creates insecure temporary dire); CVE-2023-25399 (A refcounting issue which leads to potential memory leak was discovered in scipy) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
93% confidence
Finding
Scipy has known advisories, but the requirements file does not lock a version, making it impossible to determine whether installed environments are affected. In practice, this can allow vulnerable or inconsistent builds and is especially undesirable in compliance-sensitive clinical data tooling.

Static analysis

No suspicious patterns detected.