Back to skill

Security audit

My Fitness Claw

Security checks for vulnerabilities and agentic risk

Overview

This nutrition tracker is not malicious, but it needs review because it can persist sensitive meal and health data, run an unpinned third-party dashboard script, and expose more local files than needed if the server instructions are followed.

Install only if you are comfortable with meal and nutrition history being saved in multiple local files and displayed in a browser dashboard. Use explicit meal-log commands, customize targets before relying on micronutrient advice, avoid the workspace-root HTTP server instruction, and prefer a version that bundles or pins Chart.js and removes the legacy dashboard XSS issue.

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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
canvas/index.html:145
Finding

Stored DOM Cross-Site Scripting in the Legacy Nutrition Dashboard

Content
View full analysis
0) { const categories = { "Breakfast": [], "Lunch": [], "Dinner": [], "Snacks": [] }; latest.meals.forEach(meal => { const localTime = new Date(new Date(meal.timestamp).toLocaleString('en-US', { timeZone: 'Asia/Yerevan' })); const hour = localTime.getHours(); let category = "Snacks"; if (hour >= 6 && hour < 12) category = "Breakfast"; else if (hour >= 13 && hour < 15) category = "Lunch"; else if (hour >= 19) category = "Dinner"; categories[category].push(meal); }); Object.keys(categories).forEach(cat => { if (categories[cat].length > 0) { logContent.innerHTML += `

${cat}

`; categories[cat].forEach(meal => { const time = new Date(meal.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', timeZone: 'Asia/Yerevan' }); logContent.innerHTML += `
${time}
${meal.food}
${Math.round(meal.calories)} kcal | P: ${meal.protein}g | C: ${meal.carbs}g | F: ${meal.fat}g
`; }); } }); } ``` ### Technical Analysis Meal records are loaded from `nutrition/daily_macros.json`. The legacy dashboard interpolates `meal.food`, `meal.protein`, `meal.carbs`, and `meal.fat` directly ...[truncated 1717 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:35
Finding

Workspace-Root HTTP Server Instruction Can Expose Unrelated Local Files

Content
View full analysis
📊 **View in your browser:** > - **Quick:** Open `skills/my-fitness-claw/assets/canvas/index.html` in your browser (uses offline mirror). > - **Full:** Run `python -m http.server 8000` from the workspace root and visit `http://localhost:8000/skills/my-fitness-claw/assets/canvas/index.html`. ``` ### Technical Analysis The instruction tells users to run Python's built-in HTTP server from the workspace root. The server exposes the directory from which it is started and, unless otherwise restricted, binds in a manner that can make it reachable through non-loopback interfaces. Serving the entire workspace violates least-exposure principles because the dashboard only needs files inside the Skill directory. The broader workspace may contain Agent memory, configuration files, unrelated projects, other Skills, or private documents. The server does not provide authentication or access controls. Using `localhost` in the suggested browser URL does not itself restrict the server to loopback. ### Attack Path 1. The user follows the instruction and starts `python -m http.server 8000` from the workspace root. 2. The server publishes files beneath the entire workspace directory. 3. A network peer that can reach port 8000 sends requests for known or guessed paths. 4. The server returns readable files without authentication. 5. The peer obtains unrelated workspace content that was not required for dashboard operation. When combined with the stored XSS issue in the legacy dashboard, injected browser code may also make same-origin requests for exposed workspace files. ### Impact Assessment The issue can cause unauthenticated disclosure of any readable workspace fil ...[truncated 482 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
assets/canvas/index.html:6
Finding

Unpinned Third-Party JavaScript Executes in Both Dashboards

Content
View full analysis
``` ### Technical Analysis The dashboards retrieve and execute Chart.js directly from jsDelivr. The dependency URL does not specify an exact package version and does not include a Subresource Integrity hash. As a result, the effective JavaScript executed by the dashboards can change after the Skill package has been reviewed. A compromised upstream package, CDN incident, malicious future release, or unexpected dependency change could introduce arbitrary code into the dashboard. The external request also means dashboard operation is not fully local: opening the page can disclose routine request metadata, including the user's IP address and browser headers, to the CDN. ### Attack Path 1. The user opens either dashboard while network access is available. 2. The browser requests the mutable `chart.js` package URL from jsDelivr. 3. The CDN or upstream package supplies the current JavaScript response. 4. If that response has been compromised or changed maliciously, the browser executes it automatically. 5. The supplied script runs in the dashboard page context and can access browser-visible dashboard data. ### Impact Assessment A compromised dependency can execute arbitrary JavaScript with the dashboard origin's privileges. This may permit manipulation of the displayed data, access to DOM content, same-origin requests, and network transmission of browser-accessible nutrition information. The code executes in the browser rather than directly as an operating-system process. The practical scope depends on how the dashboard is opened and which files or se ...[truncated 41 chars]
Remediation
View remediation
``` 4. Apply the fix consistently to both `assets/canvas/index.html` and `canvas/index.html`. 5. Add a Content Security Policy restricting scripts to approved local resources or the specifically required CDN origin. 6. Update the privacy documentation to disclose any remaining external network request. ]]>
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 (13)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `assets/canvas/index.html`: The visual dashboard for the OpenClaw Canvas.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
- `assets/canvas/index.html`: The visual dashboard for the OpenClaw Canvas.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documented trigger phrase 'I just ate [food name]' is broad natural language that can easily appear in ordinary conversation, increasing the chance the skill activates when the user did not explicitly intend to log a meal. Because the skill also auto-opens a dashboard whenever a meal is logged, accidental activation can lead to unintended data capture and tool invocation in routine chat.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This description imposes a demographic-specific baseline in natural language, which can create a policy issue by forcing a particular user profile without opt-in or configuration. The file does not indicate that users can choose or adjust the recommendation basis to match their own age, sex, or locale-specific guidance.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger condition 'When the user mentions eating something' is broad enough to activate on casual or hypothetical conversation, which can cause unintended logging of sensitive health and dietary information. In this skill, that risk is amplified because the workflow persists data across JSON files, browser-facing assets, and memory notes without an explicit confirmation step.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs storing meal and health-related data in multiple persistent locations, including canonical JSON, an offline browser mirror, and dated memory files, but does not clearly warn the user that personal health information will be retained and duplicated. This creates a privacy exposure surface where sensitive data may persist longer than expected, be copied into public-facing assets, or be accidentally shared when the skill directory is viewed or published.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The page imports executable JavaScript from a third-party CDN (cdn.jsdelivr.net) without integrity pinning or local bundling. If the CDN, dependency, or delivery path is compromised, attacker-controlled code would execute in the dashboard context and could read or exfiltrate meal history, nutritional data, and any other locally available skill data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The page loads Chart.js as executable JavaScript directly from a third-party CDN, which creates a supply-chain trust boundary outside the skill itself. If the CDN, dependency, or network path is compromised, arbitrary code would execute in the dashboard context and could access displayed nutritional data or manipulate the UI.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill imports third-party executable code without any user-facing disclosure even though the dashboard processes personal nutritional and meal-log data. This reduces transparency around data exposure and trust assumptions, and if the external dependency is compromised users would have no indication that outside code is participating in the page.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The instructions recommend launching a local HTTP server to view the dashboard but omit a warning that the dashboard and embedded offline nutrition data become accessible over localhost while the server is running. Although localhost is usually limited to the local machine, this still expands exposure of sensitive dietary data to other local users, browser extensions, or misconfigurations, especially since the data is mirrored into static web assets.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

This HTML/JavaScript code loads nutrition history, targets, and AI insights from local JSON files and renders meal and micronutrient details, which constitutes access to and presentation of personal health-related data. There is no visible notice, confirmation, or explanatory comment warning the user that their nutritional data will be read and shown.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The embedded default targets and notes hard-code guidance for a 'general 32-year-old male,' which can cause the application to present health-related recommendations that are inappropriate for many users without collecting or validating relevant profile information. In a nutrition skill, this is a genuine safety and quality issue because users may rely on the displayed goals and micronutrient targets as personalized advice when they are not.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The code explicitly formats timestamps using the 'en-US' locale, which forces a specific language/locale convention for users regardless of their preferences. This is a natural-language policy concern because the file does not provide locale selection or document why a fixed locale is required.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.