Back to skill

Security audit

garmin-connect-skill

Security checks for vulnerabilities and agentic risk

Overview

This Garmin health-data skill is broadly coherent, but it handles account passwords, health records, background syncing, and a hardcoded Feishu secret in ways users should review before installing.

Review this before installing. Use a disposable or rotated Garmin password if you test it, avoid passing real passwords on the command line, remove the embedded Feishu defaults, restrict permissions on ~/.garth and ~/.clawdbot, and do not enable the timer or daemon until you understand what will run and how to disable it.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/garmin-auth.py:36
Finding

Garmin Account Password Stored with Reversible Base64 Encoding and Exposed Through Command-Line Arguments

Content
View full analysis
[--cn]") print("\nExamples:") print(" Global account: python3 garmin-auth.py user@example.com password123") print(" China account: python3 garmin-auth.py user@qq.com password123 --cn") sys.exit(1) email = sys.argv[1] password = sys.argv[2] is_cn = "--cn" in sys.argv ``` ```python # scripts/garmin-sync.py:21-38 def load_credentials(): """Load saved Garmin credentials""" import base64 session_file = Path.home() / ".garth" / "session.json" if not session_file.exists(): print(f"❌ No credentials found at {session_file}") print("\nRun: python3 garmin-auth.py [--cn]") return None try: with open(session_file, 'r') as f: creds = json.load(f) # Decrypt password if 'password_encrypted' in creds: ...[truncated 2461 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/daily_health_report_feishu.py:216
Finding

Hardcoded Feishu Application Secret Enables Application Impersonation

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/garmin-sync.py:621
Finding

Sensitive Health Data Is Persisted Without Explicit Restrictive Permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/garmin-cron.sh:1
Finding

Predictable Shared Temporary Log Allows Symlink-Based File Overwrite

Content
View full analysis
/tmp/garmin-sync.log 2>&1 # Check for significant changes and alert if needed ``` ### Technical Analysis `/tmp` is generally writable by all local users. The wrapper redirects output to a fixed, predictable path using shell truncation. The shell opens the target before starting the Python command and normally follows symbolic links. A local attacker can pre-create `/tmp/garmin-sync.log` as a symbolic link to another file writable by the cron account. When the scheduled wrapper executes, the redirected output truncates and overwrites the linked target. The file may also receive detailed error messages or health-data output. Because no explicit mode is enforced, it may be readable by other local users depending on the umask and prior file ownership. The cron entry is documented rather than installed automatically, and recurring synchronization is relevant to the declared functionality. The vulnerability is therefore the unsafe logging implementation, not the mere existence of a scheduled task. ### Attack Path 1. The victim configures the documented cron entry. 2. A local attacker predicts the fixed `/tmp/garmin-sync.log` path. 3. Before the cron job runs, the attacker creates that path as a symbolic link to a target file writable by the victim account. 4. Cron invokes the wrapper as the victim. 5. Shell redirection follows the symbolic link and truncates the target. 6. Synchronization output is written into the target file, causing corruption or controlle ...[truncated 489 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Open-Ended Dependency Constraints Permit Unreviewed Future Package Releases

Content
View full analysis
=0.2.38 requests>=2.28.0 python-dateutil>=2.8.2 garth>=0.5.0 ``` ### Technical Analysis All dependencies use unrestricted lower-bound constraints. Installation can therefore resolve to any future version that satisfies the minimum, including versions that did not exist when the Skill was audited. This is particularly sensitive for `garminconnect` and `garth`, which operate in the authentication and Garmin API data path. Installed package code executes with the same local privileges as the Skill and may receive account credentials, session material, and health data. No malicious current package or unsafe package index was identified during the static audit. The confirmed weakness is the absence of reproducible, reviewed dependency resolution rather than evidence that a listed package is currently malicious. ### Attack Path 1. A user installs the Skill with `pip install -r requirements.txt`. 2. The resolver selects the newest available versions satisfying the lower bounds. 3. A dependency maintainer account, package release, or upstream build is compromised, or an incompatible release introduces a security defect. 4. The unreviewed version is downloaded and installed. 5. Package installation hooks or imported runtime code execute with the user's privileges. 6. Because the packages participate in authentication and synchronization, compromised code can access Garmin credentials, session state, and health data. ### Impact Assessment A compromised dependency can execute arbitrary code as the installing or runtime user. It could read local files, recover the Base64-stored Garmin password, access health databases, or transmit data over the network. The issue does not inherently grant privileges beyond those of the Python process, but its confidentiality a ...[truncated 64 chars]
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (89)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The finding indicates the skill may read stored Garmin credentials, use login-based handling, and backfill historical health data beyond the declared scope. In a health-data context, undeclared credential reuse and expanded collection windows increase both account compromise impact and privacy exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The finding indicates the skill may read stored Garmin credentials, use login-based handling, and backfill historical health data beyond the declared scope. In a health-data context, undeclared credential reuse and expanded collection windows increase both account compromise impact and privacy exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The finding indicates the skill may read stored Garmin credentials, use login-based handling, and backfill historical health data beyond the declared scope. In a health-data context, undeclared credential reuse and expanded collection windows increase both account compromise impact and privacy exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The finding indicates the skill may read stored Garmin credentials, use login-based handling, and backfill historical health data beyond the declared scope. In a health-data context, undeclared credential reuse and expanded collection windows increase both account compromise impact and privacy exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The finding indicates the skill may read stored Garmin credentials, use login-based handling, and backfill historical health data beyond the declared scope. In a health-data context, undeclared credential reuse and expanded collection windows increase both account compromise impact and privacy exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The finding indicates the skill may read stored Garmin credentials, use login-based handling, and backfill historical health data beyond the declared scope. In a health-data context, undeclared credential reuse and expanded collection windows increase both account compromise impact and privacy exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The finding indicates the skill may read stored Garmin credentials, use login-based handling, and backfill historical health data beyond the declared scope. In a health-data context, undeclared credential reuse and expanded collection windows increase both account compromise impact and privacy exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The finding indicates the skill may read stored Garmin credentials, use login-based handling, and backfill historical health data beyond the declared scope. In a health-data context, undeclared credential reuse and expanded collection windows increase both account compromise impact and privacy exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The finding indicates the skill may read stored Garmin credentials, use login-based handling, and backfill historical health data beyond the declared scope. In a health-data context, undeclared credential reuse and expanded collection windows increase both account compromise impact and privacy exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The finding indicates the skill may read stored Garmin credentials, use login-based handling, and backfill historical health data beyond the declared scope. In a health-data context, undeclared credential reuse and expanded collection windows increase both account compromise impact and privacy exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The finding indicates the skill may read stored Garmin credentials, use login-based handling, and backfill historical health data beyond the declared scope. In a health-data context, undeclared credential reuse and expanded collection windows increase both account compromise impact and privacy exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
86% confidence
Finding

The finding indicates the skill may read stored Garmin credentials, use login-based handling, and backfill historical health data beyond the declared scope. In a health-data context, undeclared credential reuse and expanded collection windows increase both account compromise impact and privacy exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The script contains a hardcoded default Feishu App Secret and writes it to a local config file. Embedded secrets are highly sensitive because they can be recovered from source control or copied into deployments, enabling unauthorized API use or impersonation of the Feishu application.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

Accepting the password as a command-line argument exposes it to shell history, process listings, logging, job control tooling, and possibly telemetry or audit systems. In this skill context, the script handles real account credentials for a fitness service, so leakage could enable account takeover and access to personal health and activity data.

Content

No source excerpt is available for this finding.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
92% confidence
Finding

The code invokes a shell via os.popen() to execute a Python script, which creates command-execution risk if the script path is ever influenced by environment state, filesystem manipulation, or future code changes. In this skill, the paths are currently fixed constants under the user's home directory, which lowers immediate exploitability, but using shell execution for local routing is still unsafe and unnecessarily expands the attack surface around sensitive health-data access.

Content

Scanner excerpt · scripts/garmin_quick_response.py (reported line 70)May include surrounding context.

python
if not script_path.exists():
            return f"❌ 脚本不存在:{script_path}"

        result = os.popen(f'python3 {script_path}').read()

        if not result:
            return "❌ 暂无数据"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation highlights local SQLite storage of historical health data and a session credential file but does not warn that both are sensitive artifacts requiring file-system protection. Because this skill handles personal health metrics and reusable session tokens, weak permissions, backups, or multi-user environments could expose private data or enable account reuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The README instructs users to pass Garmin credentials directly as command-line arguments, which can expose passwords through shell history, process listings, terminal logging, and remote session monitoring. In the context of a fitness-data integration that also stores long-lived session credentials, this creates a realistic risk of account compromise and unauthorized access to sensitive health data.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documents capabilities that involve reading and writing local files, invoking Python scripts, and contacting remote Garmin services, but it declares no explicit tool scope or permission boundaries. In an agent environment, that mismatch increases the risk of over-privileged execution and makes it harder for reviewers and runtime policy to constrain what the skill may access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The skill prominently states that detailed health and workout data are stored locally in SQLite but provides no privacy warning, retention guidance, or protection expectations. Because this data is sensitive medical-adjacent information, silent local persistence increases the chance of unintended disclosure to other local users, backups, or tooling.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation tells users to supply their Garmin password directly on the command line. Command-line secrets can be exposed through shell history, process lists, audit logs, screenshots, and copy/paste mistakes, making account compromise more likely.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

bash
# 已自动配置,每1小时同步一次
sudo systemctl status garmin-sync.timer

手动触发:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

bash
# 已自动配置,每1小时同步一次
sudo systemctl status garmin-sync.timer

手动触发:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

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

bash
# 已自动配置,每1小时同步一次
sudo systemctl status garmin-sync.timer

手动触发:

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
73% confidence
Finding

Enabling a service for persistence at boot creates a lasting execution path on the host. In an agent skill context, persistence deserves explicit declaration and review because it can continue accessing credentials, network resources, and local data outside an interactive session.

Content

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

bash
sudo systemctl start garmin-sync.timer
sudo systemctl enable garmin-sync.timer

查看下次同步时间:

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

The instruction to enable the timer establishes persistent scheduled execution. In a skill that handles credentials and sensitive health data, unattended recurring execution increases the blast radius of any misconfiguration, hidden behavior, or future code change because it will keep running automatically.

Content

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

bash
sudo systemctl start garmin-sync.timer
sudo systemctl enable garmin-sync.timer

查看下次同步时间:

Static analysis

No suspicious patterns detected.