T09 · Insecure Skill Coding Practices
- Location
scripts/tp.py:718- Finding
Long-Lived TrainingPeaks Credentials Exposed Through Command Arguments and Plaintext Storage
- Content
View full analysis
str | None: """Get cookie from env var or file.""" env = os.environ.get("TP_AUTH_COOKIE") if env: return env.strip() if COOKIE_FILE.exists(): return COOKIE_FILE.read_text().strip() return None def store_cookie(cookie: str) -> None: ensure_config_dir() COOKIE_FILE.write_text(cookie.strip()) # Restrict permissions try: COOKIE_FILE.chmod(0o600) except OSError: pass ``` ```python def save_token_cache(access_token: str, expires_at: float) -> None: ensure_config_dir() TOKEN_FILE.write_text(json.dumps({ "access_token": access_token, "expires_at": expires_at, })) try: TOKEN_FILE.chmod(0o600) except OSError: pass ``` ```python def exchange_cookie_for_token(cookie: str) -> dict: """Exchange Production_tpAuth cookie for OAuth token. Returns the full JSON response from /users/v3/token. """ url = f"{TP_API_BASE}{TOKEN_ENDPOINT}" headers = { "Cookie": f"Production_tpAuth={cookie}", "Accept": "application/json", } status, data = _http_request(url, "GET", headers) ``` ```python # auth p_auth = sub.add_parser("auth", help="Authenticate with a Production_tpAuth cookie") p_auth.add_argument("cookie", help="Value of the Production_tpAuth cookie") ``` The documented invocation also places the secret directly on the command line: ```bash python3 scripts/tp.py auth "" ``` ### Technical Analysis The `Production_tpAuth` value is a browser-session credential. The Skill accepts it as a positional command-line argument, which can expose it t ...[truncated 3503 chars]- Remediation
View remediation
"` example with a hidden-input authentication flow. ]]>
