Back to skill

Security audit

run-coach

Security checks for vulnerabilities and agentic risk

Overview

This skill handles sensitive running and Garmin health data, but its behavior is disclosed, user-directed, and aligned with its coaching purpose.

Install only if you are comfortable storing Garmin credentials, Garmin session tokens, and health metrics locally in the skill directory or GARMIN_DATA_DIR. Review the Telegram chat ID carefully because generated plan images are sent to that configured chat when you run the send commands. Delete garmin/activities, garmin/summary.json, and garmin/.garth when you no longer want retained Garmin data.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

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 · SKILL.md (reported line 141)May include surrounding context.

md
nothing is uploaded anywhere except the plan images you explicitly send to
  your own Telegram chat
- **Retention**: files persist until you delete them; there is no automatic
  expiry. Delete anytime: `rm -rf garmin/activities garmin/summary.json garmin/.garth`
- **Permissions**: `garmin-sync.py` enforces owner-only access on every run —
  `garmin/`, `garmin/activities/` and `garmin/.garth/` are set to 0700, and
  every snapshot, `summary.json` and token file to 0600 (existing files are

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · CHANGELOG.md (reported line 29)May include surrounding context.

md
- `garmin/garmin-sync.py`: health records and session tokens are written
    owner-only — `summary.json` and activity snapshots are created with mode
    0600, `garmin/`, `activities/` and `.garth/` set to 0700 on every run
    (pre-existing files are tightened too). Replaces the manual `chmod 700`
    step in the Data & privacy section.

## 1.1.6 (2026-08-21)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill explicitly describes capabilities to read credentials from local files, write files under its directory, invoke shell commands, and communicate over the network, but it does not declare any tool scope such as permissions or allowed-tools. That mismatch weakens least-privilege enforcement and makes it harder for a host to constrain what the skill may do, especially because it handles secrets and performs outbound network actions.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

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

bash
# Telegram (required) — skill-root dotfile, kept out of source/argv/env:
echo '{"bot_token": "<from @BotFather>", "chat_id": "<your numeric chat id>"}' > .credentials
chmod 600 .credentials
# Garmin (optional):
echo '{"email": "you@example.com", "password": "..."}' > garmin/.credentials
chmod 600 garmin/.credentials

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

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

bash
# Telegram (required) — skill-root dotfile, kept out of source/argv/env:
echo '{"bot_token": "<from @BotFather>", "chat_id": "<your numeric chat id>"}' > .credentials
chmod 600 .credentials
# Garmin (optional):
echo '{"email": "you@example.com", "password": "..."}' > garmin/.credentials
chmod 600 garmin/.credentials

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The stats command outputs sensitive wellness data such as resting heart rate, stress, body battery, fitness age, and training status, but there is no runtime warning or confirmation before disclosure. In a shared terminal, agent log, or chat-integrated execution environment, this could expose private health information without clear notice to the user.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · training/send-album.mjs (reported line 31)May include surrounding context.

js
process.exit(1);
}

const API = `https://api.telegram.org/bot${botToken}`;

if (pngFiles.length === 1) {
  // Single image: try sendPhoto, fallback to sendDocument

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · training/text-to-image-canvas.mjs (reported line 162)May include surrounding context.

js
process.exit(1);
}

const API = `https://api.telegram.org/bot${botToken}`;

if (pngFiles.length === 1) {
  // Single image: try sendPhoto, fallback to sendDocument

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · garmin/garmin-sync.py (reported line 57)May include surrounding context.

python
# Usage: send-plan.sh <caption> <html1.html> [html2.html ...]
# Multiple HTMLs are screenshotted individually and sent as a photo album.
#
# Credentials: skill-root .credentials dotfile (chmod 600) read by
# send-album.mjs directly — this script never touches them.
#
# Example (split weekly plan):

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · training/send-album.mjs (reported line 20)May include surrounding context.

js
# Usage: send-plan.sh <caption> <html1.html> [html2.html ...]
# Multiple HTMLs are screenshotted individually and sent as a photo album.
#
# Credentials: skill-root .credentials dotfile (chmod 600) read by
# send-album.mjs directly — this script never touches them.
#
# Example (split weekly plan):

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · training/send-plan.sh (reported line 7)May include surrounding context.

sh
# Usage: send-plan.sh <caption> <html1.html> [html2.html ...]
# Multiple HTMLs are screenshotted individually and sent as a photo album.
#
# Credentials: skill-root .credentials dotfile (chmod 600) read by
# send-album.mjs directly — this script never touches them.
#
# Example (split weekly plan):

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

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

Content

Scanner excerpt · training/text-to-image-canvas.mjs (reported line 23)May include surrounding context.

js
# Usage: send-plan.sh <caption> <html1.html> [html2.html ...]
# Multiple HTMLs are screenshotted individually and sent as a photo album.
#
# Credentials: skill-root .credentials dotfile (chmod 600) read by
# send-album.mjs directly — this script never touches them.
#
# Example (split weekly plan):

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script's usage text requires Chinese inputs ("标题" and "内容文本") and the generated HTML sets lang="zh", indicating the skill is designed to force a Chinese language/locale. This is a natural-language policy concern because the file does not offer any language choice or explain a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.