T09 · Insecure Skill Coding Practices
- Location
scripts/codex_profile_orchestrator.py:61- Finding
OAuth Credentials Persisted in Plaintext Registry and Backup Files
- Content
View full analysis
Vulnerability Details
File Location:
scripts/codex_profile_orchestrator.py, lines 37-41, 61-68, 263-266, 286-295, 302-305, and 629-631
Vulnerability Type: Plaintext sensitive credential storage and unnecessary credential duplication
Risk Level: MediumVulnerable Code
python def backup_file(path: Path) -> Path: backup_path = path.with_suffix(path.suffix + f'.bak-{int(time.time())}') if path.exists(): shutil.copy2(path, backup_path) return backup_pathpython def extract_identity(profile_id: str, profile: dict[str, Any]) -> dict[str, Any]: token = profile.get('access') or profile.get('token') decoded = decode_token(token) auth_payload = decoded.get('https://api.openai.com/auth') or {} profile_payload = decoded.get('https://api.openai.com/profile') or {} return { 'profileId': profile_id, 'profileBlob': deep_copy(profile), 'token': token,python if key in identities: record = identities[key] record['lastSeenAt'] = now_ms() record['profileBlob'] = deep_copy(row['profileBlob'])python identities[key] = { 'email': row.get('email'), 'userId': row.get('userId'), 'accountId': row.get('accountId'), 'canonicalId': canonical, 'kind': kind, 'firstSeenAt': now_ms(), 'lastSeenAt': now_ms(), 'profileBlob': deep_copy(row['profileBlob']), }python for record in identities.values(): canonical = record.get('canonicalId') profile_blob = record.get('profileBlob') or {} if canonical and canonical not in auth_profiles and profile_blob: auth_profiles[canonical] = deep_copy(profile_blob)python registry['lastPreferredProfileId'] = preferred_profile_id registry['updatedAt'] = now_ms() write_json(registry_path, registry) if apply else NoneTechnical Analysis
The orchestrator reads comp ...[truncated 3255 chars]
- Remediation
View remediation
Remediation Suggestions
- Remove
profileBloband all token-bearing fields from the persistent registry. Store only the canonical profile ID, normalized identity attributes, profile kind, timestamps, and health metadata. - Resolve profile credentials from the authoritative
auth-profiles.jsonfile at runtime instead of reconstructing profiles from registry copies. - If credential persistence is strictly necessary, use an operating-system credential manager such as Windows Credential Manager or another secure secret-storage mechanism. Do not rely on plaintext workspace files.
- Create sensitive files with owner-only permissions and verify existing permissions before reading or writing them. On Windows, apply an ACL limited to the intended service account.
- Replace unrestricted timestamped backups with a bounded retention policy. Store backups in a protected directory, restrict their ACLs, and securely remove expired copies.
- Add a migration routine that removes
profileBlob,access,refresh, andtokenfields from existing registry files. - Add automated tests that inspect persisted registry and backup content and fail if recognizable bearer or refresh tokens are present.
- Continue redacting credentials from console output, but treat output redaction as an additional control rather than a substitute for secure storage.
- Remove
