T09 · Insecure Skill Coding Practices
- Location
scripts/geekbi_auth.py:69- Finding
Bearer Token Persisted in Plaintext Across Multiple Storage Locations
- Content
View full analysis
Vulnerability Details
File Location:
scripts/geekbi_auth.py:69-90,scripts/geekbi_auth.py:372-386, andscripts/geekbi_auth.py:637-652
Vulnerability Type: Plaintext credential storage and excessive credential replication
Risk Level: MediumVulnerable Code
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"), )python def _write_state_files(stores, payload): normalized = _normalize_state(payload) errors = [] written = 0 for store in stores: try: _write_state_file(store, normalized) written += 1 except OSError as error: errors.append(f"{store.kind}: {_storage_probe_reason(error)}")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", ...[truncated 3172 chars]- Remediation
View remediation
Remediation Suggestions
- Store authentication state in exactly one user-specific location. Remove the skill-directory and current-working-directory stores.
- Correct the namespace from
temu-research-skillto a dedicated Ozon skill identifier to prevent cross-skill credential collisions. - Use the operating system's credential manager, such as Keychain, Credential Manager, Secret Service, or a maintained keyring abstraction, rather than plaintext JSON.
- If file storage is unavoidable, encrypt the access token with a key held by the operating-system credential service.
- Treat inability to enforce restrictive permissions as a security failure rather than silently continuing. Verify ownership and permissions before reading or writing state.
- Avoid returning credential-store filesystem paths from routine status output unless explicitly requested for diagnostics.
- Migrate existing state by reading the highest-priority legacy file once, moving the credential into the new secure store, and securely deleting all legacy copies.
- Add tests confirming that authentication creates no state files in the project directory, installation directory, or arbitrary current working directory.
- Provide token revocation and comprehensive cleanup that removes all legacy replicas if credential exposure is suspected.
