Back to skill

Security audit

NoahAI clinical-trial query

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed clinical-trial search integration that sends structured search queries and its API token to a fixed Noah endpoint, with some hardening notes but no artifact-backed malicious behavior.

Install only if you are comfortable sending clinical-trial search terms to Noah's API with your NOAH_API_TOKEN. Use a dedicated token, avoid including personal health details in queries, install dependencies in an isolated environment, and be careful with the optional --output path because it can overwrite files accessible to the running user.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T08 · Insecure Dependencies

Note
Location
SKILL.md:260
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:260; related import guidance in scripts/search.py:24-29
Vulnerability Type: Unpinned Python dependency installation
Risk Level: Low

The documentation recommends installing requests without a version constraint or integrity verification:

markdown
- `requests` library (`pip install requests`)

The script reinforces this installation instruction when the module is unavailable:

python
try:
    import requests
except ImportError:
    print("[ERROR] Missing dependency: requests\nInstall it with: pip install requests", file=sys.stderr)
    sys.exit(1)

Technical Analysis

Running pip install requests resolves whichever release the configured Python package index currently serves. The installation is not constrained by an exact version, a lock file, or package hashes. Consequently, audit results for the current dependency version do not guarantee the integrity or behavior of a version installed later.

The dependency name is the established requests package rather than an apparent typosquat, and the Skill does not automatically execute pip. This substantially limits the immediate risk. Exploitation would require compromise of the configured package index, account or release infrastructure, package-resolution configuration, or another supply-chain failure affecting a future release.

This issue does not indicate that the current project contains a malicious dependency. It is a reproducibility and supply-chain-hardening weakness.

Attack Path

  1. An operator invokes the Skill without requests installed.
  2. The script directs the operator to run pip install requests.
  3. The operator installs from a compromised or attacker-controlled configured package index, or obtains a compromised future release.
  4. Python imports the installed package when scripts/search.py starts.
  5. Malicious import-time code executes with the permis ...[truncated 980 chars]
Remediation
View remediation

Remediation Suggestions

  1. Declare dependencies in a version-controlled requirements or lock file instead of relying on an unconstrained manual installation command.

  2. Pin a reviewed version, for example:

    text
    requests==REVIEWED_VERSION
    
  3. For reproducible deployments, generate and verify hashes and install with:

    bash
    python3 -m pip install --require-hashes -r requirements.txt
    
  4. Configure installers to use an explicitly trusted package index and prevent unintended fallback to untrusted indexes.

  5. Periodically review pinned versions for known vulnerabilities and update them through a controlled review process.

  6. Run the Skill in an isolated virtual environment or container under a non-privileged account.

  7. Restrict process environment variables and outbound network access so dependencies can access only the credentials and endpoint required for clinical-trial searches.

  8. Update the missing-dependency error message to reference the reviewed requirements file rather than recommending an unconstrained pip install requests.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (7)

Tainted flow: 'headers' from os.environ.get (line 87, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/search.py (reported line 98)May include surrounding context.

python
print(f"[INFO] Query payload:\n{json.dumps(payload, indent=2)}", file=sys.stderr)

    try:
        response = requests.post(api_url, headers=headers, json=payload, timeout=30, allow_redirects=False)
        response.raise_for_status()
    except requests.exceptions.ConnectionError as e:
        raise ConnectionError(f"Cannot connect to API server: {api_url}\nDetails: {e}")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill declares runtime capabilities that include environment access, file read/write, and network use, but it does not explicitly constrain tool scope with permissions or allowed-tools. In an agent environment, this weakens least-privilege boundaries and can allow broader-than-necessary access if the skill is invoked in an unexpected context or later extended.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger description is broad enough to activate on many general biomedical or drug-development queries, not just concrete clinical trial lookups. Over-broad routing can cause the agent to send user queries and extracted entities to an external API unnecessarily, increasing data exposure and making unintended network actions more likely.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The instruction to translate non-English terms into English before querying can transmit transformed user input to an external service without user consent or confirmation. While not code-execution dangerous, it creates a privacy and correctness risk because user-provided medical terms may be altered and sent off-platform in a way the user did not request.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
60% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 272)May include surrounding context.

md
- It requires exactly one environment variable: `NOAH_API_TOKEN`. Store it in the environment or a local `.env` file, and never place it inline in commands, chats, or packaged files.
- The token is scoped to read medical public details only and cannot access private user records.
- The skill does not intentionally persist request parameters locally. Any server-side retention is determined by the NoahAI API service and its operational logging policies.
- It does not request persistent or system-level privileges and does not modify system configuration.
- The skill is source-file based (Python scripts only) and does not require runtime installs, package downloads, or external bootstrap steps.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/search.py (reported line 98)May include surrounding context.

python
print(f"[INFO] Query payload:\n{json.dumps(payload, indent=2)}", file=sys.stderr)

    try:
        response = requests.post(api_url, headers=headers, json=payload, timeout=30, allow_redirects=False)
        response.raise_for_status()
    except requests.exceptions.ConnectionError as e:
        raise ConnectionError(f"Cannot connect to API server: {api_url}\nDetails: {e}")

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script allows writing API results to any user-supplied local path via --output, which exceeds the stated search-only behavior and can overwrite arbitrary files accessible to the executing user. In an agent or automation context, this broad file-write primitive can be abused to clobber local data or place content in unintended locations.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.