Back to skill

Security audit

Nutrition tracking

Security checks for vulnerabilities and agentic risk

Overview

This nutrition-tracking skill is purpose-aligned, but it handles sensitive health data and account credentials with enough under-scoped behavior that users should review it carefully before installing.

Install only if you are comfortable sending nutrition, weight, profile, images, and coaching chat data to Haver. Verify the API origin is locked to the real Haver service, avoid exposing the hv_ API key in ordinary memory or logs, and review food or profile changes because some entries may be stored without an undo path.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:12
Finding
Unvalidated API Origin Can Receive Bearer Credentials and Sensitive Health Data<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:12`, `SKILL.md:40`, `SKILL.md:55-60`, `SKILL.md:127`, `SKILL.md:134-145`; `api-reference.md:3-10` **Vulnerability Type**: Unrestricted external API endpoint configuration **Risk Level**: High ### Vulnerable Code Snippets From `SKILL.md:12`: ```markdown You ARE the user's nutrition coach. Haver is your backend -- it stores their data, analyzes their food, calculates their metrics, and tracks their progress. You interact with it through HTTP API calls to the base URL from `HAVER_API_URL` (default: `https://haver.dev`). ``` From `SKILL.md:40`: ```http Authorization: Bearer hv_... ``` From `SKILL.md:55-60`: ```http POST {HAVER_API_URL}/api/register Content-Type: application/json { "provider": "openclaw", "externalId": "<user's unique ID>" } ``` From `api-reference.md:3-10`: ```markdown Full request/response documentation for all Haver API endpoints. All authenticated endpoints require `Authorization: Bearer hv_...` header. ## Registration ```http POST {HAVER_API_URL}/api/register Content-Type: application/json { "provider": "openclaw", "externalId": "<user's unique ID>" } ``` ``` ### Technical Analysis The Skill obtains its API origin from the `HAVER_API_URL` environment variable but does not require that the resulting origin be `https://haver.dev`, enforce HTTPS, or define redirect restrictions. Authenticated requests attach a reusable bearer credential to requests made through this configured origin. The API processes sensitive personal and health information, including food records, photographs, weight, height, age, sex, activity level, nutrition goals, and coaching conversations. If the environment variable is changed through deployment misconfiguration or attacker access to runtime configuration, the Agent may send both the bearer credential and sensitive user data to an unintended server. The same weakness also affects response integrity. A substituted server can return fabricated ...[truncated 1468 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Hard-code or strictly allowlist the production API origin: - Permit only `https://haver.dev`. - Compare the normalized scheme, host, and effective port against an exact allowlist. - Reject embedded credentials, alternate subdomains, IP-address substitutions, and nonstandard ports. 2. Require HTTPS and fail closed for all non-TLS destinations. 3. Disable redirects for authenticated requests, or validate every redirect target before following it. 4. Never forward the `Authorization` header when the redirect destination has a different origin. 5. Separate registration and authenticated API clients so credentials cannot be attached to unexpected destinations. 6. Require explicit user disclosure and consent before transmitting sensitive health information. 7. Minimize transmitted data and define retention controls for images, profile information, and conversations. 8. Add automated tests confirming that invalid origins and cross-origin redirects are rejected. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:43
Finding
Bearer API Key Is Instructed to Be Stored in Persistent Agent Memory<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:43-50`; `api-reference.md:17-18` **Vulnerability Type**: Insecure credential storage **Risk Level**: Medium ### Vulnerable Code Snippets From `SKILL.md:43-50`: ```markdown **Key lifecycle:** - **Registration** returns a fresh API key. Save it immediately as persistent memory. - **Re-registration** (same provider + externalId) generates a NEW key and invalidates the old one. This is the key recovery mechanism. - **Lost key?** Call `POST /api/register` again. You'll get a new key. The old one stops working. ``` From `api-reference.md:17-18`: ```markdown - **`apiKey`**: Always returned, even on re-register. Save immediately. - **`created`**: `true` for new users, `false` for re-registration (key rotated, old key invalidated). ``` ### Technical Analysis The Skill explicitly instructs the Agent to save a bearer API key in persistent memory. A bearer key grants access based solely on possession and should therefore be handled as a secret rather than ordinary conversational state. Persistent Agent memory may be loaded into later model contexts or exposed through memory-management features, diagnostics, backups, exports, logs, or unrelated prompts. The documentation provides no requirement for encryption, access isolation, output redaction, expiry, or use of a platform secret manager. This is distinct from intentionally poisoning memory with attacker-authored behavioral rules. The confirmed issue is insecure credential storage, best classified as an insecure Skill coding and configuration practice. ### Attack Path 1. Registration returns a credential beginning with `hv_`. 2. Following the Skill instructions, the Agent stores that credential in persistent memory. 3. A later conversation, memory export, debugging operation, log, backup, or overly broad memory-retrieval feature exposes the stored value. 4. An attacker obtains the bearer credential. 5. The attacker submits authenticated requests to H ...[truncated 605 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the instruction to place the API key in ordinary persistent Agent memory. 2. Store the credential in a dedicated platform secret manager, operating-system keychain, or encrypted credential vault. 3. Expose the secret only to the HTTP client at request time; do not place it in the model's prompt or conversational context. 4. Redact values beginning with `hv_` from logs, traces, tool output, exceptions, telemetry, and user-visible responses. 5. Apply access controls so one user, tenant, or session cannot retrieve another user's credential. 6. Support credential expiry, revocation, and rotation without requiring the model to display or manipulate the raw value. 7. Add secret-scanning tests for stored memory, logs, and generated responses. 8. Document a recovery procedure that rotates the credential immediately if exposure is suspected. ]]>

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:127
Finding
Untrusted API Response Strings Are Relayed Directly to Users<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:127-133`; `api-reference.md:47-49`; `coaching-guide.md:7-15`, `coaching-guide.md:73` **Vulnerability Type**: Untrusted remote-content propagation **Risk Level**: Medium ### Vulnerable Code Snippets From `SKILL.md:127-133`: ```markdown ### Logging Food `POST /api/me/nutrition/log` -- body: `{ "text": "...", "images?": [...] }` Returns: `{ text, foodLogged, sideEffectMessages[] }` Always relay `sideEffectMessages` to the user. Be specific about portions and cooking methods. Rough estimates are fine. ### Nutrition Summary `GET /api/me/nutrition/summary` -- query: `date`, `from`, `to` (all optional) Returns: `{ text, date }` -- the `text` is already well-formatted, present it directly. ``` From `coaching-guide.md:7-15`: ```markdown Both `POST /api/me/nutrition/log` and `POST /api/me/chat` can return `sideEffectMessages` -- an array of strings containing XP awards, streak notifications, brain snacks, and milestone achievements. **Always relay these to the user.** They're motivational triggers designed to reinforce good habits. Examples: - `"🔥 3-day streak! +15 XP"` - `"🧠 New brain snack earned: 'Protein helps repair muscles after exercise'"` - `"🏆 Milestone: First week of consistent logging!"` Don't silently swallow these -- they're a key part of the engagement loop. ``` From `coaching-guide.md:73`: ```markdown - **Nutrition summaries**: Use the `text` field directly -- it's already well-formatted ``` ### Technical Analysis The Skill treats `text` and `sideEffectMessages` returned by a remote service as trusted presentation content and directs the Agent to reproduce them without validation. These fields are server-controlled data, not trusted Skill instructions. A compromised Haver backend, malicious intermediary under a broken TLS model, or substituted endpoint through the configurable `HAVER_API_URL` setting could return deceptive instructions, phishing links, advertisements, false hea ...[truncated 1785 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat all API response fields as untrusted data rather than instructions. 2. Validate responses against a strict schema, including expected types, maximum lengths, character restrictions, and allowed message categories. 3. Do not reproduce remote strings verbatim by default. Extract verified data and render it using locally controlled templates. 4. Strip or neutralize links, credential requests, executable markup, prompt-like directives, and unsupported health claims. 5. Clearly separate remote data from trusted Skill instructions and prohibit the Agent from obeying instructions embedded in response fields. 6. Permit only predefined side-effect event types, such as validated XP amounts or milestone identifiers, and map them to local display text. 7. Add provenance labeling when remote free-form content must be displayed. 8. Log and reject anomalous responses while ensuring logs do not contain API keys or unnecessary health information. 9. Combine these controls with strict API-origin allowlisting and TLS enforcement. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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)

Natural-Language Policy Violations

High
Confidence
98% confidence
Finding
The skill directs the agent to set the user's language automatically based on platform-provided information and explicitly forbids asking the user. This removes user choice and transparency around use of inferred/profile data, and can lead to silent preference manipulation or incorrect data submission without user awareness.

Context Leakage

High
Category
Data Exfiltration
Content
## Step 3: Physical Profile

Collect conversationally -- sex, age, height, weight, activity level.

```http
POST {HAVER_API_URL}/api/me/onboarding/profile
Confidence
84% confidence
Finding
The instruction to collect profile details conversationally increases the chance that sensitive health and demographic information will be gathered in free-form chat and then forwarded to backend services. In this health-oriented skill, such data can reveal intimate personal attributes, so insufficient scoping, notice, or safeguards raises the risk of context leakage and over-collection.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The manifest advertises broad trigger terms such as 'food', 'weight', 'diet', 'meal', and 'coaching', which can match common everyday requests outside a narrowly scoped nutrition-tracking intent. This increases the chance the skill is invoked unexpectedly and then begins collecting or acting on sensitive health-related data in contexts where the user did not clearly intend to engage this service.

Natural-Language Policy Violations

Medium
Confidence
98% confidence
Finding
The onboarding instructions say to set language automatically based on platform knowledge and explicitly not ask the user. That removes user choice over a profile setting and relies on cross-context inference about the user, which can cause incorrect configuration and privacy concerns, especially in a health-related skill processing sensitive data.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The endpoint documentation instructs clients to transmit food logs and optional food images, which are health-related and potentially highly sensitive personal data, but it provides no warning about remote processing, storage, retention, or privacy implications. In a nutrition and health-tracking skill, users may disclose medical, dietary, and lifestyle information they would not expect to be sent to a third-party AI service without explicit notice.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The chat endpoint accepts free-form text and optional images for AI coaching, and the metadata indicates the chat may trigger side effects such as logging food from conversation content. That combination creates a meaningful privacy and integrity risk because users may unknowingly send sensitive health information and cause state-changing actions without a clear warning that their data is remotely processed and may alter their account records.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
ISO 639-1 codes. Common: `"en"` (English), `"uk"` (Ukrainian).

**You already know the user's language** -- OpenClaw provides it. Set this automatically without asking. Don't prompt the user for language selection.

## Step 2: Timezone
Confidence
90% confidence
Finding
The directive 'Don't prompt the user' explicitly suppresses user involvement in a decision that writes to their profile. In the context of a health and nutrition assistant handling personal data, suppressing confirmation makes the overall onboarding process less transparent and increases the chance of unnoticed incorrect or undesired settings.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
ISO 639-1 codes. Common: `"en"` (English), `"uk"` (Ukrainian).

**You already know the user's language** -- OpenClaw provides it. Set this automatically without asking. Don't prompt the user for language selection.

## Step 2: Timezone
Confidence
90% confidence
Finding
The directive 'Don't prompt the user' explicitly suppresses user involvement in a decision that writes to their profile. In the context of a health and nutrition assistant handling personal data, suppressing confirmation makes the overall onboarding process less transparent and increases the chance of unnoticed incorrect or undesired settings.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The onboarding flow instructs the agent to collect and transmit sensitive health-related profile data, including sex, age, height, weight, activity level, and later weight goals, without any requirement to disclose privacy handling, obtain explicit consent, or minimize collection. In a nutrition and health-tracking context, this is materially sensitive personal data, so silent collection and API submission increase privacy and compliance risk.

Static analysis

No suspicious patterns detected.