Back to skill

Security audit

HealthOS

Security checks for vulnerabilities and agentic risk

Overview

This skill is not malicious, but it deserves Review because it gives broad read access to sensitive Apple Health records and persists a bearer token with limited hardening guidance.

Install only if you are comfortable letting the agent read broad HealthOS/Apple Health data, including raw samples and events. Use the narrowest read-scoped token available, store it in a protected secret mechanism or locked-down config file, rotate or revoke it if exposed, and ask for explicit confirmation before broad raw archive lookups.

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

Warning
Location
GUIDE.md:57
Finding
Plaintext Storage of a Sensitive HealthOS API Token## Vulnerability Details **File Location**: `GUIDE.md`, lines 57–60 **Vulnerability Type**: Plaintext credential storage guidance **Risk Level**: Medium ### Vulnerable Code Snippet ```markdown For a *new* user account: 1. Generate a token: **app → Settings → Health data → API** (or the developer page), or `POST /api/v1/tokens` with the four read scopes. 2. Set it in Quark: add `HEALTHOS_API_TOKEN` to `env.vars` in `/root/.openclaw/openclaw.json` (or the equivalent agent env). ``` ### Technical Analysis The setup guide instructs users to place `HEALTHOS_API_TOKEN` in a general JSON configuration file. A bearer token is equivalent to a password for the permissions assigned to it. Storing it as plaintext in a regular configuration file exposes it to any user, process, backup system, diagnostic collector, or support bundle that can read or copy that file. The project does not require restrictive permissions for this configuration file, recommend a dedicated secret store, or provide token rotation and revocation guidance. Although the client itself does not print the token and only sends it to the fixed HealthOS API origin, those runtime safeguards do not protect the credential while it is stored on disk. ### Attack Path 1. A local process, compromised agent component, administrator, backup operator, or other party obtains read access to `/root/.openclaw/openclaw.json` or a copied backup. 2. The party extracts the plaintext value assigned to `HEALTHOS_API_TOKEN`. 3. The token is supplied as a bearer credential to `https://api.healthosx.com/api`. 4. The party invokes API endpoints authorized by the token, such as health summaries, metrics, sleep records, workouts, catalog information, coverage information, or raw archive endpoints. 5. Access remains possible until the token expires or is explicitly revoked. This exploitation path depends on an attacker first obtaining access to the configuration file; the findin ...[truncated 847 chars]
Remediation
## Remediation Suggestions 1. Store the API token in the platform's dedicated secret-management facility rather than in the general OpenClaw JSON configuration. 2. Inject the token into `HEALTHOS_API_TOKEN` only at runtime, ensuring it is not written to command histories, prompts, logs, diagnostic output, or source-controlled files. 3. If file-backed storage is unavoidable: - Place the token in a dedicated secrets file rather than the general configuration. - Restrict ownership to the service account that runs the agent. - Apply owner-only permissions, such as mode `0600`. - Exclude the file from source control, backups, support bundles, and diagnostic collectors unless those systems provide equivalent encryption and access controls. 4. Continue granting only the minimum required read scopes and avoid broader or separately scoped health-data permissions. 5. Document procedures for immediate token revocation and rotation after suspected disclosure. 6. Prefer short-lived credentials where the HealthOS API supports them, and periodically rotate long-lived personal tokens. 7. Update the setup guide to explain that bearer tokens are sensitive credentials and must not be placed in ordinary plaintext configuration without appropriate protection.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger condition says the skill activates automatically when a question is about health data, which is broad enough to catch ordinary health-related conversation and send it into a skill with access to sensitive synced Apple Health records. In this context, over-triggering increases the chance of unnecessary access, processing, or disclosure of private medical and wellness information.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The guide states the configured token has only four read scopes for summary, metrics, sleep, and workouts, but it also documents direct use of raw-archive commands such as catalog, coverage, samples, and events. That mismatch can cause operators and users to misunderstand the true data exposure and may lead to broader-than-disclosed access being granted or relied upon for highly sensitive health data retrieval.

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill uses sensitive capabilities (environment token access and outbound network access) but does not explicitly declare tool scope such as permissions or allowed-tools. That weakens platform-level containment and review, making it easier for an agent to invoke capabilities the user or host may not have clearly consented to, especially given the skill handles sensitive health data.

External Transmission

Medium
Category
Data Exfiltration
Content
# The API origin is fixed: the bearer token must never be sent to a
# user/config-controlled host. This is deliberate and not overridable.
API_URL = "https://api.healthosx.com/api"
TOKEN = os.environ.get("HEALTHOS_API_TOKEN", "")

# Browser User-Agent: the API is behind Cloudflare, which rejects unknown
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# The API origin is fixed: the bearer token must never be sent to a
# user/config-controlled host. This is deliberate and not overridable.
API_URL = "https://api.healthosx.com/api"
TOKEN = os.environ.get("HEALTHOS_API_TOKEN", "")

# Browser User-Agent: the API is behind Cloudflare, which rejects unknown
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# The API origin is fixed: the bearer token must never be sent to a
# user/config-controlled host. This is deliberate and not overridable.
API_URL = "https://api.healthosx.com/api"
TOKEN = os.environ.get("HEALTHOS_API_TOKEN", "")

# Browser User-Agent: the API is behind Cloudflare, which rejects unknown
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# The API origin is fixed: the bearer token must never be sent to a
# user/config-controlled host. This is deliberate and not overridable.
API_URL = "https://api.healthosx.com/api"
TOKEN = os.environ.get("HEALTHOS_API_TOKEN", "")

# Browser User-Agent: the API is behind Cloudflare, which rejects unknown
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
# The API origin is fixed: the bearer token must never be sent to a
# user/config-controlled host. This is deliberate and not overridable.
API_URL = "https://api.healthosx.com/api"
TOKEN = os.environ.get("HEALTHOS_API_TOKEN", "")

# Browser User-Agent: the API is behind Cloudflare, which rejects unknown
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.