T09 · Insecure Skill Coding Practices
- Location
- scripts/codex-add-profile.sh:24
- Finding
- Persistent Plaintext Backups of OAuth Credentials## 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**: Medium ### Vulnerable 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 `cp` does not independently enforce a secure mode such as `0600`; resulting protection depends on source permissions, platform behavior, the user's `umask`, and parent-directory access controls. Timestamp-based n ...[truncated 1720 chars]
- Remediation
- ## Remediation Suggestions 1. 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" ``` 2. 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")" ``` 3. Delete temporary credential backups after successful restoration and profile import: ```bash rm -f -- "$CODEX_BACKUP" "$OPENCLAW_BACKUP" ``` 4. 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. 5. Validate that the authentication directories are owned by the current user and are not group- or world-writable before creating sensitive files. 6. 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. 7. Recommend revoking and reauthorizing affected OAuth sessions if historical backup permissions may have allowed unauthorized access.
