{"description":"Trending threats, MITRE ATT\u0026CK coverage, and detection metadata. Fed continuously.","feed_url":"https://feed.craftedsignal.io/products/garminconnect--0.3.4/feed.json","home_page_url":"https://feed.craftedsignal.io/","items":[{"_cs_actors":[],"_cs_cpes":[],"_cs_cves":[],"_cs_exploited":false,"_cs_has_poc":false,"_cs_poc_references":[],"_cs_products":["garminconnect (\u003c= 0.3.4)"],"_cs_severities":["high"],"_cs_tags":["insecure-permissions","credential-theft","local-privilege-escalation","vulnerability"],"_cs_type":"advisory","_cs_vendors":[],"content_html":"\u003cp\u003eThe \u003ccode\u003egarminconnect\u003c/code\u003e Python library, specifically versions 0.3.4 and older, contained a critical vulnerability (CVE-2026-54447) related to insecure file permission assignment. When the library created or updated the \u003ccode\u003egarmin_tokens.json\u003c/code\u003e file, which stores sensitive Garmin OAuth refresh tokens, it failed to explicitly set restrictive file permissions. Under common Linux and macOS \u003ccode\u003eumask\u003c/code\u003e settings, this resulted in the \u003ccode\u003egarmin_tokens.json\u003c/code\u003e file being world-readable (0o644). This flaw allowed any unprivileged local user on a multi-user system to read the file, extract the refresh token, and consequently gain persistent, unauthorized access to the victim's Garmin Connect account. This issue was identified and reported by EQSTLab. The vulnerability impacts users who have configured the \u003ccode\u003egarminconnect\u003c/code\u003e library to interact with their Garmin accounts on shared host environments.\u003c/p\u003e\n\u003ch2 id=\"attack-chain\"\u003eAttack Chain\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eA user installs and configures the \u003ccode\u003egarminconnect\u003c/code\u003e library version 0.3.4 or earlier on a multi-user Linux or macOS system and authenticates with their Garmin Connect account.\u003c/li\u003e\n\u003cli\u003eThe \u003ccode\u003egarminconnect\u003c/code\u003e library calls \u003ccode\u003eClient.dump()\u003c/code\u003e, persisting OAuth tokens, including the \u003ccode\u003edi_refresh_token\u003c/code\u003e and \u003ccode\u003edi_client_id\u003c/code\u003e, to the file \u003ccode\u003e~/.garminconnect/garmin_tokens.json\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eDue to the \u003ccode\u003eClient.dump()\u003c/code\u003e function not specifying a \u003ccode\u003emode\u003c/code\u003e argument for file creation, and the system operating under a default umask (e.g., \u003ccode\u003e022\u003c/code\u003e), the \u003ccode\u003egarmin_tokens.json\u003c/code\u003e file is created with world-readable permissions (0o644).\u003c/li\u003e\n\u003cli\u003eA separate, unprivileged local user on the same shared system discovers and reads the \u003ccode\u003e~/.garminconnect/garmin_tokens.json\u003c/code\u003e file, which contains the sensitive OAuth refresh token.\u003c/li\u003e\n\u003cli\u003eThe attacker extracts the \u003ccode\u003edi_refresh_token\u003c/code\u003e and \u003ccode\u003edi_client_id\u003c/code\u003e from the world-readable JSON file.\u003c/li\u003e\n\u003cli\u003eThe attacker then uses the stolen \u003ccode\u003edi_refresh_token\u003c/code\u003e and \u003ccode\u003edi_client_id\u003c/code\u003e to exchange for fresh access tokens from Garmin's OAuth endpoint, bypassing the need for re-authentication.\u003c/li\u003e\n\u003cli\u003eThe attacker uses these valid access tokens to gain unauthorized, persistent access to the victim's Garmin Connect account, enabling access to health data, activity history, and device management features.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"impact\"\u003eImpact\u003c/h2\u003e\n\u003cp\u003eSuccessful exploitation of CVE-2026-54447 leads to local credential theft and unauthorized access to victims' Garmin Connect accounts. On multi-user Linux or macOS hosts, any local, unprivileged user can read the \u003ccode\u003egarmin_tokens.json\u003c/code\u003e file, which contains the refresh token. This allows the attacker to obtain persistent access to the victim's Garmin Connect data, including sensitive health and fitness information, activity history, and device management capabilities, until the stolen refresh token is explicitly revoked. The primary risk is unauthorized access to personal data and potential account hijacking.\u003c/p\u003e\n\u003ch2 id=\"recommendation\"\u003eRecommendation\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eUpgrade garminconnect\u003c/strong\u003e: Immediately upgrade the \u003ccode\u003egarminconnect\u003c/code\u003e library to version 0.3.5 or later to mitigate CVE-2026-54447 by running \u003ccode\u003epip install --upgrade garminconnect\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eRemediate existing files\u003c/strong\u003e: Manually set secure permissions for the token store by executing \u003ccode\u003echmod 700 ~/.garminconnect\u003c/code\u003e and \u003ccode\u003echmod 600 ~/.garminconnect/garmin_tokens.json\u003c/code\u003e to protect existing \u003ccode\u003egarmin_tokens.json\u003c/code\u003e files.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eRotate compromised tokens\u003c/strong\u003e: If the \u003ccode\u003egarmin_tokens.json\u003c/code\u003e file was exposed on a shared host, treat the refresh token as compromised. Delete the existing token store (e.g., \u003ccode\u003erm ~/.garminconnect/garmin_tokens.json\u003c/code\u003e) and log in again using the \u003ccode\u003egarminconnect\u003c/code\u003e library to mint a fresh, securely stored token.\u003c/li\u003e\n\u003c/ul\u003e\n","date_modified":"2026-07-15T17:34:40Z","date_published":"2026-07-15T17:34:40Z","id":"https://feed.craftedsignal.io/briefs/2026-07-insecure-garminconnect-permissions/","summary":"The `garminconnect` Python library versions 0.3.4 and earlier insecurely assigned world-readable file permissions to the `garmin_tokens.json` OAuth token store, allowing local attackers on multi-user systems to steal refresh tokens and gain persistent, unauthorized access to victims' Garmin Connect accounts.","title":"Insecure Permission Assignment for Garmin OAuth Token Store","url":"https://feed.craftedsignal.io/briefs/2026-07-insecure-garminconnect-permissions/"}],"language":"en","title":"CraftedSignal Threat Feed - Garminconnect (\u003c= 0.3.4)","version":"https://jsonfeed.org/version/1.1"}