T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/geekbi_auth.py:66
- Finding
- Bearer Token Replicated Across Multiple Local Storage Locations<![CDATA[ ## Vulnerability Details **File Location**: `scripts/geekbi_auth.py:66-89`, `scripts/geekbi_auth.py:637-649` **Vulnerability Type**: Excessive plaintext credential storage **Risk Level**: Medium ### Complete Code Snippet ```python def _user_config_state_path(): return _absolute_path( user_config_path("GeekBI", appauthor=False, ensure_exists=True) / "temu-research-skill" / AUTH_FILE_NAME ) def _skill_state_path(): return _absolute_path(Path(__file__).parent.parent / AUTH_STATE_DIR / AUTH_FILE_NAME) def _workspace_state_path(): return _absolute_path(Path(os.getcwd()) / AUTH_STATE_DIR / AUTH_FILE_NAME) def _resolve_stores(): candidates = ( ResolvedStore(_user_config_state_path(), "user-config-directory"), ResolvedStore(_skill_state_path(), "skill-directory"), ResolvedStore(_workspace_state_path(), "working-directory"), ) ``` The returned access token is subsequently placed in the state that is written to these stores: ```python def save_token(latest): latest_server = latest["servers"].get(server_key) if not isinstance(latest_server, dict): return False, False latest_pending = latest_server.get("pending") if not isinstance(latest_pending, dict): return False, False if latest_pending.get("deviceCode") != pending.get("deviceCode"): return False, False _remove_access_token(latest_server) latest_server["accessToken"] = access_token latest_server["accessTokenExpiresAt"] = now + max(0, expires_in - 30) latest_server.pop("pending", None) return True, True ``` ### Technical Analysis The authentication state, including a bearer access token, is mirrored to three locations: 1. A user configuration directory. 2. The installed Skill directory. 3. A `.geekbi` directory under the current working directory. Only one protected credential location is required for the declared AliExpress research functionality. Replication i ...[truncated 1999 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Persist authentication state in only one dedicated user credential location. 2. Remove the Skill-directory and current-working-directory stores. 3. Prefer an operating-system credential manager or secret-storage API instead of a plaintext JSON file. 4. Replace the unrelated `temu-research-skill` namespace with an AliExpress-specific application namespace. 5. Add a migration that: - Reads existing legacy state once. - Moves it to the protected canonical location. - Securely removes obsolete copies where feasible. 6. Preserve restrictive file permissions and fail closed if they cannot be established. 7. Store only the minimum required token fields and avoid persisting device codes or navigation URLs longer than necessary. 8. Document token lifetime, revocation behavior, storage location, and cleanup procedures. ]]>
