Back to skill

Security audit

Lovefromio Garmin Health Analysis

Security checks for vulnerabilities and agentic risk

Overview

The skill is a Garmin health helper, but this package includes a plaintext Garmin email and password and under-discloses several ways sensitive health data can be stored or exposed.

Do not install this published version as-is. The publisher should remove artifact/config.json from the package, rotate the exposed Garmin password and invalidate sessions, pin dependencies in an isolated environment, remove command-line password examples, harden token and export-file permissions, bundle or integrity-pin dashboard JavaScript, and add clear privacy warnings for health, profile, and GPS data.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
config.json:2
Finding

Plaintext Garmin Account Credentials Packaged with the Skill

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
install.sh:20
Finding

Unpinned Dependencies Installed into User or System Python Environments

Content
View full analysis
/dev/null; then echo "✓ Dependencies installed (--user)" elif pip3 install --break-system-packages garminconnect fitparse gpxpy 2>/dev/null; then echo "✓ Dependencies installed (--break-system-packages)" elif pip3 install garminconnect fitparse gpxpy 2>/dev/null; then echo "✓ Dependencies installed (system-wide)" else ``` Related unpinned installation instructions also appear in `SKILL.md`, `README.md`, and `references/mcp_setup.md`. The MCP instructions additionally tell users to clone a separate repository and run `npm install`. ### Technical Analysis The installer retrieves the latest available versions of `garminconnect`, `fitparse`, `gpxpy`, and their transitive dependencies without a lockfile, integrity hashes, or reviewed version constraints. Consequently, the code executed by an installation can change after the Skill itself has been audited. The fallback to `--break-system-packages` bypasses protections intended to prevent modifications to a distribution-managed Python environment. The final fallback may attempt a system-wide installation, depending on the execution environment and pip configuration. No evidence shows that the named dependencies are currently malicious. The vulnerability is the absence of controls that ensure users install the same reviewed artifacts. ### Attack Path 1. An attacker compromises a dependency maintainer account, package release, package index, or transitive dependency. 2. The attacker publishes a malicious version under a dependency name used by the installer. 3. A user runs `install.sh` or follows the documented unpinned installation command. 4. `pip` resolves and installs the attacker-controlled version. 5. Malicious installation hooks or imported runtime co ...[truncated 679 chars]
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/garmin_chart.py:29
Finding

Remote CDN JavaScript Executes in Dashboards Containing Sensitive Health Data

Content
View full analysis
``` The same generated document embeds Garmin health data into the JavaScript execution context: ```javascript const chartsData = {json.dumps(charts_data)}; ``` ### Technical Analysis Generated dashboards load executable JavaScript from jsDelivr each time they are opened. No Subresource Integrity attribute or restrictive Content Security Policy is applied. The remote script executes in the same document that contains sleep, HRV, heart-rate, recovery, calorie, and activity information. A compromised CDN response, compromised upstream package artifact, or maliciously altered remote resource could read the embedded `chartsData` object and transmit it to an external endpoint. This network request also conflicts with the documentation's broad claims that the Skill connects only to Garmin and performs no external data sharing. Loading Chart.js is functional rather than intentionally malicious, but remote executable content is not the minimum-risk mechanism needed to render a local dashboard. ### Attack Path 1. The user requests a Garmin dashboard. 2. The Skill retrieves sensitive health information and embeds it into a generated HTML file. 3. The user opens the generated file in a browser. 4. The browser requests Chart.js from jsDelivr. 5. If the returned resource has been maliciously modified, it executes within the dashboard document. 6. The malicious script reads `chartsData`. 7. The script sends the health and activity data to an attacker-controlled server. ### Impact Assessment Successful exploitation can disclose the health and activity data included in the dashboard. Depending on dashboard type, this may include sleep hi ...[truncated 290 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/garmin_auth.py:128
Finding

Garmin Password Accepted Through Process Command-Line Arguments

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/garmin_auth.py:43
Finding

Token File Permissions Are Not Explicitly Enforced Before or After Storage

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The declared description presents a broad conversational Garmin analytics skill spanning many wellness and recovery metrics plus dashboards. The supplied code chunk only handles downloading activity files and parsing/analyzing local FIT/GPX activity data. It supports route/activity-centric metrics and simple querying, which aligns with a subset of the description (FIT/GPX download, route analysis, some pace/elevation/HR extraction). However, the primary behavior is much narrower than declared, and major advertised capabilities—natural-language access, sleep/recovery metrics, Body Battery, HRV, VO2 max, training readiness, body composition, SPO2, weekly workout summaries across account data, and dashboard generation—are absent from this code. Therefore the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a full Garmin data analysis skill with broad end-user functionality around querying health metrics, workouts, files, and dashboards. The supplied code chunk instead only handles authentication: loading credentials from config/env/CLI, logging into Garmin Connect, saving tokens to a local token store, and checking auth status. Authentication can be a supporting detail, but here the chunk's actual behavior is materially narrower than the declared purpose and includes an undeclared capability involving credential handling and token persistence. Therefore the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code’s actual function is much narrower than the declared description. It generates interactive HTML dashboards/charts from a handful of Garmin metrics and can save/open them locally. That partially matches the 'generate interactive health dashboards' part of the description, but it does not implement the broader declared experience of talking to Garmin data naturally or answering arbitrary questions. It also lacks the advertised capabilities for FIT/GPX downloads, route/elevation/pace analysis, and many named metrics. Because the primary behavior in this code chunk is chart generation from limited Garmin data rather than a natural-language multi-capability Garmin assistant, this is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description presents a broad natural-language Garmin analytics skill with extensive metric coverage, file download support, route/point-in-time analysis, and dashboard generation. The supplied code is much narrower: it is a backend-style data fetcher with command-line arguments that retrieves only several daily/summary Garmin Connect datasets and prints JSON. Many headline capabilities in the description are absent from this code chunk, especially FIT/GPX download, arbitrary time/route analysis, interactive dashboards, and broad metric support. Additionally, the code fetches user profile information including email, which is not called out in the description. While the implemented subset is related to Garmin health data, the actual behavior materially underdelivers relative to the declared purpose, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description presents a comprehensive Garmin data assistant with extensive natural-language querying, many health metrics, file download and route analysis, and dashboard generation. The supplied code chunk only implements a small subset: parsing a requested time/date and fetching the nearest datapoint for heart rate, stress, Body Battery, or steps from Garmin. While this is consistent with one example from the description (e.g., heart rate at 3pm), it materially underdelivers relative to the declared purpose and omits most of the advertised capabilities. Therefore the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/mcp_setup.md (reported line 28)May include surrounding context.

md
# Install and setup
npm install
pip3 install garminconnect fitparse gpxpy
cp .env.example .env
# Edit .env with your credentials

# Authenticate

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/mcp_setup.md (reported line 29)May include surrounding context.

md
npm install
pip3 install garminconnect fitparse gpxpy
cp .env.example .env
# Edit .env with your credentials

# Authenticate
npm run auth

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill requests and documents use of sensitive capabilities including environment access, shell execution, and file read/write, but it does not declare an explicit tool scope or permissions boundary. That increases the chance an agent will grant broader access than necessary, enabling credential exposure or unintended filesystem/shell actions during normal use.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The description invites very broad natural-language use across sensitive health data and local analysis actions without clear operational constraints. In an agent setting, vague scope can lead to over-invocation, unnecessary data access, or use in contexts the author did not intend, especially when shell and filesystem capabilities are also involved.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
84% confidence
Finding

The skill instructs users to persist credentials in a local config file and also stores reusable session tokens on disk. Local secret persistence increases the blast radius of workstation compromise, accidental backup leakage, or overly permissive file permissions, particularly because the data involved is personal health information.

Content

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

Option B: Local Config File

Create a config file in the skill directory:

bash
cd ~/.clawdbot/skills/garmin-health-analysis

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The instructions recommend passing the Garmin password directly on the command line, which can expose secrets through shell history, process listings, logging, and agent telemetry. Because these are account credentials for sensitive health data, disclosure could lead to account compromise and privacy loss.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · install.sh (reported line 34)May include surrounding context.

sh
exit 1
fi

# Create config from example if it doesn't exist
if [ ! -f "config.json" ] && [ -f "config.example.json" ]; then
    echo
    echo "📝 Creating config.json from example..."

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The authentication section shows use of raw email/password login and direct storage/reuse of OAuth session tokens, but does not warn that these values are secrets that must be protected from logs, prompts, screenshots, repos, or plaintext local storage. In a health-data skill, exposed credentials or tokens could let an attacker access sensitive Garmin account data, including activity history and biometric information, and potentially maintain session access through token reuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The document presents body composition, SPO2, respiration, stress, and other health metrics as routine capabilities without acknowledging that they are highly sensitive personal health data. Without disclosure or caution, users may not understand the risks of exposing or retaining these metrics, which could lead to privacy harm or inappropriate downstream sharing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This documentation encourages downloading and analyzing FIT/GPX activity files containing precise GPS routes and sensitive biometric data such as heart rate, elevation, cadence, and power, but provides no warning about the privacy implications or safe handling of those files. In the context of a health-analysis skill, exposing location traces and physiological data can enable tracking of home/work locations, routines, and sensitive health inferences if users or downstream tools mishandle the exported data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This debug script prints raw device, sleep, and heart-rate data directly to stdout, which can expose highly sensitive health information in terminals, CI logs, shell history captures, or remote debugging sessions. In a health-analysis skill, this is more concerning because the data includes biometric and wellness details that are private by nature, even if the script appears intended only for local debugging.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script downloads highly sensitive health and location data and writes it to disk automatically, defaulting to /tmp, without any consent prompt, sensitivity warning, restrictive permissions, or cleanup. In the context of a Garmin health-analysis skill, exported FIT/GPX files can contain precise routes, timestamps, heart rate, and other biometric data, so leaving them on shared or predictable filesystem locations increases the risk of unintended disclosure to other local users, processes, backups, or logs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script accepts the Garmin account password via the --password CLI argument, which can expose credentials through shell history, process listings, job control logs, and system monitoring tools visible to other local users or administrators. In a health-data skill, compromise of these credentials can grant access to sensitive personal wellness, activity, and location information, making the issue more serious than a generic low-sensitivity account helper.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code writes a generated dashboard containing Garmin health metrics to a user-specified path, which can persist sensitive personal data on disk. Although the script logs that the file was saved, it does not warn the user that the output contains private health information or prompt before creating a persistent file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

When no output path is provided, the script saves the generated dashboard to a temporary file and launches it in the default browser. While it prints that it is opening the chart, it does not disclose that sensitive Garmin health data is being written to a local temp file and exposed to the browser environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This script fetches highly sensitive health and activity data from Garmin and emits it to stdout for agent parsing, but provides no user-facing warning, consent checkpoint, or safeguards against downstream logging/exposure. Because stdout is commonly captured by agent frameworks, shells, logs, or debugging systems, sensitive medical-adjacent data could be disclosed beyond the user's expectation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script exposes profile PII including name, display name, and email via the profile metric and prints it directly to stdout. In a health-analysis skill, disclosing identity data beyond the stated analytics purpose expands data exposure and creates unnecessary privacy risk if logs, transcripts, or downstream tools capture the output.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This script retrieves highly sensitive health data and prints it directly to stdout as formatted JSON, which can easily be captured by calling agents, logs, terminal history, or other integrations without any privacy warning, minimization, or confirmation step. In the context of a natural-language Garmin analysis skill, broad access to intraday heart rate, SPO2, body composition, hydration, and stress data increases the chance of over-collection and unintended disclosure of personal health information.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The inline comments are written in Chinese while the rest of the script and outputs are in English, creating an implicit language constraint for maintainers or users reading the file. There is no indication that this locale choice is optional or justified as region-specific.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.