Back to skill

Security audit

garmin connect cn

Security checks for vulnerabilities and agentic risk

Overview

This Garmin skill appears purpose-built for Garmin Connect CN data, but it handles sensitive health data with overly broad activation and stores reusable passwords locally.

Install only if you are comfortable giving this skill Garmin Connect CN account access, including health, activity, and possible GPS data. Before use, prefer a sandbox or dedicated account, avoid typing passwords in shared terminals, review or remove ~/.config/garmin-cn/credentials.json after use, and be aware that login may delete ~/.garth session cache used by other Garmin/Garth tools.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/garmin_cli.py:41
Finding

Garmin Password Stored in Plaintext and Exposed Through Command-Line Arguments

Content
View full analysis
login ``` The documentation states that these credentials are saved in: ```text ~/.config/garmin-cn/credentials.json ``` ### Technical Analysis The account password is serialized directly into a JSON file without encryption or integration with an operating-system credential store. File mode `0600` reduces exposure to other local users, but it does not protect the password from: - Malicious software or processes running as the same user. - Accidental inclusion in backups, support bundles, or home-directory archives. - Disclosure through local filesystem compromise. - Theft after compromise of the user account. The parent configuration directory is created without an explicit restrictive mode. Although the credential file is changed to `0600` after writing, there is a short interval between file creation and `chmod` during which the effective permissions depend on the process umask. The password is also accepted as a positional command-line argument. Depending on the operating system and shell, it may be visible in shell history, process listings, terminal logs, automation logs, or audit records. Network authentication itself is consistent with the declared Garmi ...[truncated 1317 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:96
Finding

Unpinned Third-Party Packages Are Installed and Executed at Runtime

Content
View full analysis
/scripts/garmin_cli.py status ``` ```bash python3 -m pip install -q garminconnect python3 /scripts/garmin_cli.py status ``` ```bash uv run --python 3.11 --with fitparse python /scripts/fit_file_parser.py --help ``` ```bash python3 -m pip install -q fitparse python3 /scripts/fit_file_parser.py --help ``` ### Technical Analysis The setup instructions install `garminconnect` and `fitparse` without pinning reviewed versions or verifying package hashes. Consequently, the code executed by the Skill can change after the Skill itself has been reviewed. The package names are consistent with the libraries imported by the scripts, and the repository contains no evidence of deliberate typosquatting or an explicitly malicious source. Nevertheless, retrieving the latest package version at execution time creates a supply-chain trust boundary that is not controlled by the audited artifact. Python package installation and import can execute package-controlled code. A compromised maintainer account, malicious upstream release, dependency compromise, or package-index incident could therefore introduce arbitrary behavior into the Skill environment. ### Attack Path 1. An upstream package or one of its transitive dependencies is compromised. 2. A malicious release is published under the legitimate package name. 3. The Agent follows the documented setup instructions without a version or hash constraint. 4. `uv` or `pip` downloads and installs the compromised release. 5. Package-controlled code executes during installation, import, or normal API use. 6. The malicious code accesses the user's Garmin credentials, health data, exported activity files, or other files available to th ...[truncated 622 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/garmin_cli.py:48
Finding

Authentication Retry Recursively Deletes a Shared User-Wide Garth Cache

Content
View full analysis
0: clear_garth_cache() return get_client(retries=retries - 1) ``` It is also invoked before every explicit login: ```python def cmd_login(args): clear_garth_cache() client = Garmin(args.email, args.password, is_cn=True) ``` ### Technical Analysis The Skill's own configuration namespace is `~/.config/garmin-cn`, but cache clearing recursively removes the separate user-wide `~/.garth` directory. That directory may be shared by unrelated applications using the Garth library. The operation is triggered automatically for any exception raised during login, not only an error conclusively caused by an expired token. Therefore, transient network failures, server errors, dependency defects, or malformed responses can cause destructive deletion of unrelated session state. Using `ignore_errors=True` suppresses deletion failures and prevents reliable reporting of what was removed. The behavior exceeds the minimum filesystem access needed to query Garmin data because the Skill could instead use a dedicated cache directory or remove only its own stale session. ### Attack Path 1. The user invokes `login`, or a normal command calls `get_client()`. 2. The login attempt fails for any reason and enters the generic exception handler. 3. The program recursively deletes `~/.garth`. 4. Cached ...[truncated 873 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:3
Finding

Skill Metadata Encourages Account Access for Generic Health Questions Without Explicit User Intent

Content
View full analysis
Query personal health and activity data from Garmin Connect CN. Whenever the user mentions Garmin, asks about running pace, sleep quality, HRV, Body Battery, VO2 Max, training status, or any health metric, or wants to export activity files, this Skill should be activated with priority—even if the user did not explicitly say to query Garmin or use Garmin. ``` ### Technical Analysis The Skill handles highly sensitive health, activity, and location information. Its activation instructions are broader than its declared integration boundary because generic questions about sleep, pacing, HRV, or health metrics do not necessarily imply consent to access an authenticated Garmin account. The instruction to prioritize activation even without an explicit Garmin request can alter the Agent's normal decision-making and cause unnecessary tool use. This violates data-minimization and purpose-limitation principles: an informational question may be answered without retrieving private account data. No evidence shows that the Skill sends this information to an attacker-controlled endpoint. The risk is unintended retrieval and disclosure within the current session. ### Attack Path 1. A user asks a generic question about sleep quality, running pace, HRV, or another supported health metric. 2. The Agent follows the front-matter instruction an ...[truncated 894 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented behavior claims broad Garmin Connect CN querying, health dashboard access, exports, and analysis, while the analyzed implementation reportedly does not provide most of that functionality. This mismatch is dangerous because users or upstream agents may trust the skill with sensitive health requests and credentials under false assumptions, leading to over-activation, unsafe handoffs, or credential collection for unsupported operations.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The activation text tells agents to prioritize this skill even when the user did not explicitly ask for Garmin, which can cause overbroad interception of generic health or activity queries. In context, this is especially risky because the skill handles sensitive health data and login credentials, so unnecessary activation can expose private data paths or prompt for secrets when a simpler non-sensitive response would suffice.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill asks for Garmin account email and password and stores credentials locally, but it does not present a prominent warning, consent flow, retention policy, or safer authentication alternative. For a health-data skill, that omission is significant because users may disclose highly sensitive credentials without understanding storage, reuse, or compromise risks.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The skill directly collects and stores account credentials in ~/.config/garmin-cn/credentials.json, creating a local secret store that could be exposed through host compromise, backups, misconfigured permissions, or other tools with filesystem access. Because the account grants access to personal health and activity history, compromise of this file can lead to privacy violations and unauthorized account access.

Content

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

login <邮箱> <密码>

text

凭据保存在 `~/.config/garmin-cn/credentials.json`(权限 600,仅本人可读)。

---

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/advanced-usage.md (reported line 106)May include surrounding context.

bash
# 假设最终摘要为 $TEST_ROOT/analysis/final_summary.json
rm -rf "$TEST_ROOT/raw" "$TEST_ROOT/exports" "$TEST_ROOT/logs"
find "$TEST_ROOT/analysis" -type f ! -name "final_summary.json" -delete

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/garmin_cli.py (reported line 28)May include surrounding context.

python
Garmin = None

CONFIG_DIR = os.path.expanduser("~/.config/garmin-cn")
CREDENTIALS_FILE = os.path.join(CONFIG_DIR, "credentials.json")


# ── Helpers ───────────────────────────────────────────────────────────

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code silently saves credentials after login and later reuses them for authentication, without any explicit warning, consent flow, or confirmation that the password will be stored locally. This creates a deceptive handling of highly sensitive credentials and increases the likelihood users unknowingly leave long-term secrets on disk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill instructs the agent to read from the filesystem, execute shell commands, install packages, and write files, but it declares no explicit tool scope or permission boundaries. In an agent ecosystem this increases the blast radius of accidental or unauthorized execution, because a caller may activate the skill without realizing it needs shell, file read, and file write capabilities.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The applicable-scenario list covers very broad categories like sleep, HRV, heart rate, stress, VO2 Max, and activity history without exclusion criteria, making it easy for the skill to trigger on ordinary wellness questions unrelated to Garmin. That broad trigger surface is more dangerous here because the skill subsequently steers toward shell execution and account-backed data access, increasing the chance of unnecessary collection or exposure of sensitive data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation instructs users to pass email and password directly on the command line for login. Command-line credentials are commonly exposed via shell history, process listings, CI logs, and terminal recording, which can leak Garmin account access and associated sensitive health data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script stores the user's Garmin email and password directly in ~/.config/garmin-cn/credentials.json as plaintext. Even with file mode 0600, any local compromise, backup exposure, malware, or accidental file disclosure immediately reveals reusable account credentials, which is especially sensitive because this skill accesses personal health and activity data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

User-facing strings throughout the CLI are written only in Chinese, including errors, help text, and status messages, with no option to select another language or locale. This creates a language/locale policy issue because the skill effectively forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

整个文档以中文撰写,且未说明这是面向特定中文区域用户的受限技能,也未提供语言选择或替代说明。按规则,若技能强制特定语言而没有用户 opt-in 或正当的区域性说明,可构成自然语言层面的语言/locale 政策问题。

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

This code performs a filesystem write when --output is provided, creating parent directories and overwriting the target file contents, but there is no confirmation prompt, explicit warning print, or comment/docstring disclosing that behavior. For a code file, file writes should have some visible disclosure unless already clearly warned elsewhere in the skill documentation, which is not available in this file.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.