T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/geekbi_auth.py:70
- Finding
- Bearer Token Is Unnecessarily Replicated Across Multiple Local Directories## Vulnerability Details **File Location**: `scripts/geekbi_auth.py:70-83, 385-398, 637-648` **Vulnerability Type**: Sensitive credential exposure through excessive local persistence **Risk Level**: Medium ### Vulnerable 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) ``` ```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)}") if written == 0: reason = ";".join(errors) or "登录状态目录不可用" raise OSError(reason) ``` ```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 includes a bearer access token and is mirrored into three locations: 1. A per-user configuration directory. 2. The installed Skill directory. 3. A `.geekbi` directory under the current working directory. Only one protecte ...[truncated 2487 chars]
- Remediation
- ## Remediation Suggestions 1. Store authentication state only in a protected, per-user configuration or operating-system credential store. 2. Remove `_skill_state_path()` and `_workspace_state_path()` from `_resolve_stores()` so bearer tokens are never mirrored into installation or working directories. 3. Rename the user configuration subdirectory from `temu-research-skill` to an Ozon-specific identifier to prevent cross-Skill state collisions. 4. Prefer the operating system's native secret facility, such as Windows Credential Manager, macOS Keychain, or Secret Service-compatible storage on Linux. 5. If file storage remains necessary, enforce owner-only access on all supported operating systems, including explicit Windows ACL configuration. 6. Implement a migration that reads a legacy state once, moves it into the protected canonical store, and securely deletes all legacy replicas. 7. Avoid retaining pending device codes and bearer tokens longer than required, and provide reliable server-side token revocation in addition to local deletion. 8. Add tests confirming that authentication creates exactly one credential-bearing state file and never writes credentials beneath the current working directory or Skill installation directory. 9. Document the storage location, token lifetime, cleanup behavior, and security assumptions for users and administrators.
