T09 · Insecure Skill Coding Practices
- Location
scripts/daily_health_report_feishu.py:225- Finding
Hard-Coded Feishu Application Credentials
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This Garmin skill has a coherent fitness-sync purpose, but it mishandles account passwords, shared app secrets, persistence, and private health data enough that it should be reviewed before installation.
Install only after reviewing and preferably fixing the credential handling. Do not pass your Garmin password on the command line, rotate any Feishu secret that may be real, run the sync only as your normal user, restrict ~/.garth and ~/.clawdbot permissions, avoid shared machines, and verify any webhook or report destination before enabling automatic reports.
scripts/daily_health_report_feishu.py:225Hard-Coded Feishu Application Credentials
scripts/garmin-auth.py:36Garmin Password Stored with Reversible Base64 Encoding
scripts/garmin-sync.py:624Sensitive Health Data Written and Printed Without Adequate Confidentiality Controls
scripts/garmin-cron.sh:8Predictable Temporary Log Enables Health-Data Disclosure and Symlink File Clobbering
scripts/daily_health_report_webhook.py:146Health Reports Can Be Sent to an Unrestricted Webhook Destination
scripts/garmin_quick_response.py:20Execution of Replaceable Scripts from an External Home-Directory Path
scripts/garmin_db_reader.py:78SQL Query Limits Are Constructed Through String Interpolation
requirements.txt:1Security-Sensitive Dependencies Are Not Reproducibly Pinned
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
Background daemons, PID/lock files, lifecycle controls, and retry behavior are not inherently malicious, but they are significant operational behaviors omitted from the declared purpose. Undeclared persistence and long-running execution can surprise operators and expand the attack surface, particularly on systems where skills are expected to be transient.
The script contains hardcoded Feishu App ID and App Secret, embedding live third-party credentials in source code. Anyone with access to the skill can reuse these credentials to obtain tokens and operate the associated Feishu app, potentially impersonating the bot, sending messages, or abusing tenant resources.
The hardcoded App Secret is persisted locally and then used for outbound API calls, creating both secret exposure and poor credential-handling practice. Even though the file mode is restricted, storing a real shared secret in plaintext on disk and shipping a default secret in code greatly increases the chance of unauthorized reuse and long-term compromise.
The docstring states credentials are saved securely, but the implementation only base64-encodes the password, which is trivially reversible and provides no real confidentiality. This is dangerous because it can mislead users and reviewers into believing the stored secret is protected when anyone with filesystem access can recover the plaintext password immediately.
The script persists the user's Garmin password after login in base64-obfuscated form and does so without a strong warning that the secret is written to disk and recoverable. In the context of a fitness sync skill, this is especially risky because compromise of the local machine or backup artifacts could expose the user's Garmin account credentials, enabling account takeover and access to personal health data.
The usage instructions tell users to pass their password as a command-line argument, which commonly leaks secrets through shell history, process listings, terminal logging, and monitoring tools. This is dangerous because even if the file permissions are restricted later, the password may already have been exposed to other local users, system telemetry, or support logs at invocation time.
The code executes a shell command via os.popen using a dynamically constructed command string. Although script_path is selected from hardcoded Path objects in this file, invoking a shell is still dangerous because the path is derived from the user's home directory and can contain shell metacharacters or point to attacker-controlled files in a writable location, leading to command injection or unintended code execution.
if not script_path.exists():
return f"❌ 脚本不存在:{script_path}"
result = os.popen(f'python3 {script_path}').read()
if not result:
return "❌ 暂无数据"
The README instructs users to pass Garmin account passwords directly on the command line, which commonly exposes secrets through shell history, process listings, terminal logging, and support screenshots. Because these credentials grant access to personal fitness and health data, disclosure can lead to account compromise and privacy harm beyond the local machine.
The README documents storage of health data in a local SQLite database and OAuth/session credentials in a predictable filesystem location, but provides no warning about their sensitivity or the need for access controls. On shared systems, backups, or compromised user accounts, these files can expose intimate health information and reusable session material.
The skill documentation describes capabilities that imply file access, shell execution, persistence, and network use, but it does not declare any explicit tool scope or permissions boundary. In an agent ecosystem, this increases the chance that the skill is granted broader-than-necessary powers or that reviewers underestimate what it can do.
The skill stores sensitive health data locally in SQLite but provides no user-facing warning about privacy, retention, access controls, or backup exposure. Health metrics such as sleep, HRV, heart rate, and body battery are sensitive personal data, so silent local persistence increases privacy risk.
The instructions tell users to place their Garmin password directly on the command line. Command-line arguments are commonly exposed through shell history, process listings, logs, and support screenshots, making credential disclosure far more likely.
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.
# 已自动配置,每1小时同步一次
sudo systemctl status garmin-sync.timer
手动触发:
No suspicious patterns detected.