Back to skill

Security audit

Open Health

Security checks for vulnerabilities and agentic risk

Overview

The skill appears purpose-aligned, but it books real mental-health appointments while handling sensitive patient data with insufficient safeguards.

Review before installing. This skill can create real appointments and transmit sensitive mental-health, identity, contact, and insurance data to an external service. Use it only where users clearly intend to book, require explicit confirmation before the final booking call, and avoid command-line or logging paths that expose the patient JSON.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/booking-api.sh:47
Finding
Sensitive Patient Data Exposed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/booking-api.sh:47-56` **Related Documentation**: `SKILL.md:136-142`, `SKILL.md:167-169` **Vulnerability Type**: Sensitive data exposure through process arguments and command logging **Risk Level**: High ### Vulnerable Code ```bash book|book-dry) json="${1:-}" [ -z "$json" ] && error "Usage: booking-api.sh book '<json-payload>'" url="${BASE_URL}/api/v1/book" [ "$command" = "book-dry" ] && url="${url}?mode=dry_run" curl -s -X POST \ -H "Content-Type: application/json" \ -d "$json" \ "$url" | python3 -m json.tool ``` The documented invocation explicitly places the complete patient record in a command-line argument: ```bash scripts/booking-api.sh book '{"provider_id":"...","session_id":"...","service":"...","slot":"...","patient_first_name":"...","patient_last_name":"...","patient_email":"...","patient_phone":"...","patient_dob":"...","patient_state":"...","insurance_carrier":"...","insurance_member_id":"..."}' ``` ### Technical Analysis The booking payload contains sensitive identity, contact, insurance, and healthcare information, including: - Patient name - Date of birth - Email address - Telephone number - State - Requested mental-health service - Insurance carrier - Insurance member or subscriber ID The script accepts this complete JSON document through `$1`. Consequently, it appears in the argument list of the shell script process. The script then supplies the same value to `curl` using `-d "$json"`, exposing the payload in the `curl` process argument list as well. Depending on the execution environment, command arguments may be captured by: - Agent tool-call or execution telemetry - Shell command history when invoked interactively - Process-monitoring and endpoint-observability systems - Debug traces such as `set -x` - Audit logging or error-reporting infrastructure - Local users or services permitted to inspect same-user processes This beh ...[truncated 1927 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Accept booking data only through standard input.** Do not accept sensitive JSON as a positional command-line argument. For example: ```bash book|book-dry) [ "$#" -eq 0 ] || error "Pass the booking payload through standard input" url="${BASE_URL}/api/v1/book" [ "$command" = "book-dry" ] && url="${url}?mode=dry_run" curl --silent --show-error --fail-with-body \ -X POST \ -H "Content-Type: application/json" \ --data-binary @- \ "$url" | python3 -m json.tool ;; ``` 2. **Update the documented invocation** so that the payload is supplied through a protected standard-input channel rather than written literally into an interactive command. The invoking agent should use an execution interface capable of providing stdin separately from command metadata. 3. **Avoid intermediate files.** If a temporary file is unavoidable, create it with restrictive permissions such as mode `0600`, store it only in a trusted local directory, and remove it reliably with a signal-safe cleanup trap. 4. **Disable and prohibit shell tracing** around booking operations. Ensure neither the script nor its caller enables `set -x`, because tracing can disclose stdin-derived values if they are later expanded in shell commands. 5. **Redact execution telemetry.** Configure the agent runtime, process supervisor, audit pipeline, and error-reporting system not to record booking request bodies, stdin, expanded environment variables, or API responses containing patient data. 6. **Minimize in-memory copies.** Stream the request body directly from stdin to `curl` with `--data-binary @-` instead of storing the complete payload in a shell variable. 7. **Strengthen transport error handling.** Use `--fail-with-body`, `--show-error`, and appropriate connection and request timeouts so failed HTTP responses are handled explicitly without encouraging diagnostic logging of the sensitive request body. 8. **Add regression tests** that inspect spaw ...[truncated 163 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (10)

External Script Fetching

High
Category
Supply Chain
Content
case "$command" in
  services)
    curl -sf "${BASE_URL}/api/v1/services" | python3 -m json.tool
    ;;

  availability)
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
[ -n "$date" ]      && qs="${qs}&date=${date}"
    [ -n "$time_pref" ] && qs="${qs}&time_preference=${time_pref}"

    curl -sf "${BASE_URL}/api/v1/availability?${qs}" | python3 -m json.tool
    ;;

  book|book-dry)
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

External Script Fetching

High
Category
Supply Chain
Content
url="${BASE_URL}/api/v1/book"
    [ "$command" = "book-dry" ] && url="${url}?mode=dry_run"

    curl -s -X POST \
      -H "Content-Type: application/json" \
      -d "$json" \
      "$url" | python3 -m json.tool
Confidence
90% confidence
Finding
Remote code is downloaded and executed. This bypasses code review and could introduce malicious code.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill invokes shell and network capabilities (`curl`, `python3`, and `scripts/booking-api.sh`) while declaring no explicit tool scope or permission boundaries. In an environment where skills may be installed broadly, this creates an over-privileged and opaque execution model that can enable unintended command execution or outbound data transmission, especially dangerous because the workflow handles sensitive health and identity data.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger condition activates on broad mentions of mental health topics rather than requiring clear booking intent, so the skill may begin a healthcare booking flow during casual or exploratory conversation. In this context, that increases the risk of collecting sensitive health and insurance information without sufficient user intent confirmation or context-appropriate consent.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
"That slot was just taken — want me to search for the next available?"

On validation error:
Fix and retry. Don't ask the user to re-enter everything.

## Important Rules
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
The skill tells the agent to collect highly sensitive PII and then forbids storing it in variables, even though constructing the required booking JSON payload necessarily requires transient storage and transformation. This contradiction encourages undefined or ad hoc handling of patient data, increasing the chance that PII is logged, leaked into memory/summaries, or mishandled by implementations trying to satisfy incompatible requirements.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documented booking flow collects highly sensitive personal and health-related data, including full name, contact details, date of birth, state, insurance carrier, and insurance member ID, yet the API reference explicitly states that no authentication is required and provides no privacy, consent, minimization, or secure-handling guidance. In a mental-health telehealth context, this increases the risk of unauthorized collection, misuse, or disclosure of regulated health and insurance information, especially if integrators treat the public endpoint as safe to call without strong user notice and controls.

External Transmission

Medium
Category
Data Exfiltration
Content
url="${BASE_URL}/api/v1/book"
    [ "$command" = "book-dry" ] && url="${url}?mode=dry_run"

    curl -s -X POST \
      -H "Content-Type: application/json" \
      -d "$json" \
      "$url" | python3 -m json.tool
Confidence
94% confidence
Finding
The script transmits arbitrary JSON booking payloads to a third-party telehealth endpoint, which likely includes sensitive personal and health information. In the context of a mental-health booking skill, this is especially sensitive because PHI/PII may be sent without visible consent, minimization, schema validation, or safeguards against accidental over-collection.

Natural-Language Policy Violations

Low
Confidence
73% confidence
Finding
The description repeatedly constrains the service to US providers, US states, and US insurance carriers, presenting that scope as mandatory behavior. While this may be operationally necessary, the file does not frame it as a user choice or explicit region-specific limitation in a way that avoids a locale-policy concern under the stated rule.

Static analysis

No suspicious patterns detected.