Back to skill

Security audit

garmin-connect-health

Security checks across malware telemetry and agentic risk

Overview

This Garmin health skill does what it says and discloses its sensitive local storage, but users should protect the cached health data and tokens.

Install only if you are comfortable giving the skill access to your Garmin account and storing detailed health history on this machine. Prefer Keychain or environment variables over CLI passwords, keep GARMIN_DATA_DIR and GARMIN_TOKENSTORE in private directories, and delete the local cache if you no longer want the data retained.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (7)

Tainted flow: 'cache_file' from os.environ.get (line 416, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
p(f"  本周运动: 中强度 {result.get('weekly_moderate_minutes')}min  高强度 {result.get('weekly_vigorous_minutes')}min / 目标 {result.get('weekly_intensity_goal')}min")

    # ── 保存 JSON ──────────────────────────────
    with open(cache_file, "w", encoding="utf-8") as f:
        json.dump(result, f, ensure_ascii=False, indent=2)

    if target_date == str(date.today()):
Confidence
87% confidence
Finding
The output path is derived from GARMIN_DATA_DIR, which is environment-controlled, and the script writes highly sensitive health data to that location without validating or constraining the destination. In an agent or automation context, a manipulated environment could redirect writes to unintended files or shared locations, causing privacy leakage or clobbering of user data.

Tainted flow: 'latest_file' from os.environ.get (line 760, credential/environment) → open (file write)

Medium
Category
Data Flow
Content
if target_date == str(date.today()):
        latest_file = os.path.join(DATA_DIR, "latest.json")
        with open(latest_file, "w", encoding="utf-8") as f:
            json.dump(result, f, ensure_ascii=False, indent=2)

    # ── 写入 SQLite daily_summary ──────────────
Confidence
87% confidence
Finding
The latest.json path is constructed from the same environment-controlled data directory and receives a full copy of the user's current health dataset. If the environment is attacker-influenced or the directory is shared, this can expose sensitive medical and activity information or overwrite files in unintended locations.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill documentation clearly describes capabilities that access environment variables, invoke shell commands, and write local files/SQLite data, yet no explicit permissions are declared. This creates a transparency and governance gap: an agent or user may invoke a skill with filesystem and credential-handling behavior without an up-front permission model, increasing the chance of unsafe execution or unintended access to sensitive local data.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The changelog explicitly states that health and fitness data is stored locally in SQLite and JSON, but provides no warning about persistence, retention, or protection of sensitive health data. In the context of a health-data skill, undocumented local persistence increases the risk of accidental exposure through backups, shared machines, weak filesystem permissions, or later exfiltration by other local processes.

Vague Triggers

Medium
Confidence
74% confidence
Finding
The example trigger phrases are very broad natural-language requests such as 'Show my health data' and 'What's my HRV?', which could overlap with ordinary assistant queries. In an agent environment, broad triggers can cause accidental invocation of a credentialed skill that accesses sensitive health data when the user may only be asking a general question or seeking non-tool-based advice.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script persistently stores extensive health, biometric, sleep, stress, activity, and training data in plaintext JSON and SQLite under the user's home directory, but it provides no meaningful privacy notice, consent gate, retention policy, or file-permission hardening. Because this is sensitive health data, local persistence materially increases the harm from endpoint compromise, shared accounts, backups, or accidental disclosure.

Session Persistence

Medium
Category
Rogue Agent
Content
conn = sqlite3.connect(DB_PATH)
    conn.execute("PRAGMA journal_mode=WAL")
    conn.executescript("""
    CREATE TABLE IF NOT EXISTS daily_summary (
        date TEXT PRIMARY KEY,
        fetched_at TEXT,
        steps INTEGER,
Confidence
93% confidence
Finding
The skill stores long-lived, richly detailed health and activity records in a local SQLite database, creating persistent exposure of sensitive data beyond the immediate fetch operation. In the context of a health-data skill, session/data persistence is materially more dangerous because the stored information includes biometrics, sleep, stress, activities, and training status that can reveal medical and lifestyle patterns.

VirusTotal

65/65 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

No suspicious patterns detected.