T09 · Insecure Skill Coding Practices
- Location
scripts/codex-cli-sync.py:55- Finding
Plaintext OAuth credential backups may be created with unsafe permissions
- Content
View full analysis
Vulnerability Details
File Location:
scripts/codex-cli-sync.py, lines 55–59
Vulnerability Type: Insecure storage of sensitive credentials
Risk Level: MediumVulnerable Code
python def backup_file(path: Path) -> Path | None: if not path.exists(): return None backup = path.with_name(f"{path.name}.bak-{time.strftime('%Y%m%d-%H%M%S')}") backup.write_bytes(path.read_bytes()) return backupThe function is called before the token-bearing OpenClaw profile store is updated:
python prof_backup = backup_file(PROFILES_PATH) state_backup = backup_file(STATE_PATH) if not args.no_set_first else None store["profiles"][profile_id] = credential atomic_write_json(PROFILES_PATH, store)Technical Analysis
auth-profiles.jsoncontains OAuth access and refresh tokens. Before modifying that file,backup_file()creates a complete plaintext copy under a timestamped.bak-*filename.The backup is created through
Path.write_bytes()without explicitly setting owner-only permissions. Its effective permissions therefore depend on the process umask and parent-directory access controls. Under a permissive environment, another local user or process may be able to read the backup.These backups also have no retention or cleanup mechanism. Consequently, expired and potentially still-valid refresh tokens can remain on disk after the active credential store has changed. This increases both the number of credential copies and the duration of exposure.
Attack Path
- A legitimate user runs
python3 scripts/codex-cli-sync.py. - The script reads the existing OpenClaw profile store containing OAuth credentials.
backup_file()writes the entire store to a timestamped plaintext backup.- The backup receives permissions based on the runtime umask rather than an explicit
0600policy. - If the file and parent directories are accessible, another local principa ...[truncated 919 chars]
- A legitimate user runs
- Remediation
View remediation
Remediation Suggestions
- Create backup files atomically with explicit owner-only permissions, such as
os.open()withO_CREAT | O_EXCL | O_WRONLYand mode0o600. - Apply
os.chmod(backup, 0o600)after creation as defense in depth, while avoiding any interval in which the file is broadly readable. - Verify that the OpenClaw credential directory is owner-controlled and not writable or traversable by unrelated users.
- Preserve restrictive permissions when replacing the primary credential store; explicitly enforce
0600on token-bearing files. - Implement bounded backup retention and promptly remove obsolete credential backups.
- Warn users that backups contain complete plaintext credentials.
- Revoke affected OAuth sessions and delete exposed backups if permissive backups may already have been created.
- Consider encrypting backups with a user-controlled key or omitting automatic credential backups unless the user explicitly requests them.
- Create backup files atomically with explicit owner-only permissions, such as
