T09 · Insecure Skill Coding Practices
- Location
scripts/codex-add-profile.sh:24- Finding
Persistent Plaintext Backups of OAuth Credentials
- Content
View full analysis
Vulnerability Details
File Location:
scripts/codex-add-profile.sh, lines 24-27, 54-69, and 178-184
Vulnerability Type: Sensitive credential storage in persistent plaintext backups
Risk Level: MediumVulnerable Code
bash CODEX_AUTH="$HOME/.codex/auth.json" CODEX_BACKUP="${CODEX_AUTH}.bak-$(date +%s)" OPENCLAW_BACKUP="${OPENCLAW_AUTH}.bak-$(date +%s)" # Step 1: Back up both files echo "==> Backing up existing auth files" if [ -f "$CODEX_AUTH" ]; then cp "$CODEX_AUTH" "$CODEX_BACKUP" # Verify backup succeeded if [ ! -f "$CODEX_BACKUP" ]; then echo "Error: Failed to create backup at $CODEX_BACKUP" exit 1 fi echo " Codex CLI: $CODEX_BACKUP" fi if [ -f "$OPENCLAW_AUTH" ]; then cp "$OPENCLAW_AUTH" "$OPENCLAW_BACKUP" if [ ! -f "$OPENCLAW_BACKUP" ]; then echo "Error: Failed to create backup at $OPENCLAW_BACKUP" exit 1 fi echo " OpenClaw: $OPENCLAW_BACKUP" fi echo "" echo "==> Done! Profile openai-codex:$PROFILE_NAME added." echo " OpenClaw backup: $OPENCLAW_BACKUP" echo " Codex backup: $CODEX_BACKUP"Technical Analysis
The script copies two authentication files into timestamped backup files:
~/.codex/auth.json, which may contain live Codex OAuth access and refresh tokens.~/.openclaw/agents/main/agent/auth-profiles.json, which contains imported OAuth credentials for one or more profiles.
These backups are retained after a successful execution. No cleanup, expiration, rotation, encryption, or explicit restrictive permission enforcement is applied. Every execution can therefore create additional credential-bearing files that remain usable until their tokens expire or are revoked.
The use of
cpdoes not independently enforce a secure mode such as0600; resulting protection depends on source permissions, platform behavior, the user'sumask, and parent-directory access controls. Timestamp-based n ...[truncated 1720 chars]- Remediation
View remediation
Remediation Suggestions
-
Create backup files with explicit owner-only permissions:
bash umask 077 install -m 600 "$CODEX_AUTH" "$CODEX_BACKUP" install -m 600 "$OPENCLAW_AUTH" "$OPENCLAW_BACKUP" -
Use securely generated, collision-resistant temporary names rather than timestamp-only names:
bash CODEX_BACKUP="$(mktemp "${CODEX_AUTH}.bak.XXXXXXXX")" OPENCLAW_BACKUP="$(mktemp "${OPENCLAW_AUTH}.bak.XXXXXXXX")" -
Delete temporary credential backups after successful restoration and profile import:
bash rm -f -- "$CODEX_BACKUP" "$OPENCLAW_BACKUP" -
If rollback backups must be retained, require explicit user opt-in and implement a bounded retention policy. Store retained backups in an owner-only directory, enforce mode
0600, and clearly instruct users how and when to remove them. -
Validate that the authentication directories are owned by the current user and are not group- or world-writable before creating sensitive files.
-
Preserve the existing trap-based restoration behavior, but extend cleanup handling so temporary backups are securely removed only after restoration has succeeded. Avoid deleting the sole valid backup when restoration fails.
-
Recommend revoking and reauthorizing affected OAuth sessions if historical backup permissions may have allowed unauthorized access.
-
