T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/garmin_client.py:34
- Finding
- Automatic Access to Credentials Stored by Unrelated Skills<![CDATA[ ## Vulnerability Details **File Location**: `scripts/garmin_client.py:34-36, 40-48, 52-61` **Vulnerability Type**: Cross-skill credential access **Risk Level**: High ### Vulnerable Code ```python FALLBACK_ENV_FILES = [ Path.home() / ".workbuddy" / "skills" / "run-coach__skillhub" / ".env", Path.home() / ".workbuddy" / "skills" / "coros-mcp-energy-lab__skillhub" / ".env", ] def _read_env_file(path: Path, key: str) -> str: if not path.exists(): return "" try: for line in path.read_text(encoding="utf-8").splitlines(): line = line.strip() if line.startswith(key + "="): return line.split("=", 1)[1].strip().strip('"').strip("'") except Exception: pass return "" def _env_or_envfile(key: str) -> str: val = os.environ.get(key, "").strip() if val: return val for path in [ENV_FILE] + FALLBACK_ENV_FILES: val = _read_env_file(path, key) if val: return val return "" ``` ### Technical Analysis The Skill automatically probes `.env` files belonging to two unrelated installed Skills and extracts `GARMIN_EMAIL`, `GARMIN_PASSWORD`, and `GARMIN_IS_CN`. This crosses the logical trust boundary between Skills. Garmin authentication is necessary for the declared functionality, but reading secret files owned by other Skills is not necessary. Credentials could instead be supplied through process environment variables, this Skill's own configuration file, an OS credential manager, or an explicitly selected credential file. The implementation does not require explicit consent before accessing the sibling files. It also does not validate file ownership, symbolic links, or restrictive file permissions. A maliciously prepared path or compromised sibling Skill could therefore influence the credentials used by this Skill. ### Attack Path 1. A user installs this Skill alongside one of the named fallback Skills. 2. The user stores Garmin ...[truncated 1092 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove `FALLBACK_ENV_FILES` and all automatic probing of other Skills' directories. 2. Accept credentials only from: - `GARMIN_EMAIL`, `GARMIN_PASSWORD`, and `GARMIN_IS_CN` process environment variables; - this Skill's own protected `.env`; or - an OS-backed credential manager. 3. If cross-Skill reuse is required, require an explicit command-line option such as `--credential-file PATH` and display the selected path before reading it. 4. Reject symbolic links where feasible and verify that the credential file is owned by the current user. 5. On POSIX systems, reject or warn about credential files accessible by group or other users. 6. Avoid long-term password storage after token enrollment when the Garmin client supports token-only reuse. 7. Document credential scope, storage, and rotation procedures. ]]>
