T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/provision_config.py:104
- Finding
- Configuration Backup May Expose Sensitive Data Through Insecure File Permissions## Vulnerability Details **File Location**: `scripts/provision_config.py`, lines 104–105 **Vulnerability Type**: Insecure creation of a sensitive configuration backup **Risk Level**: Medium ### Vulnerable Code ```python backup_path = f"{config_path}.bak.{ts}" Path(backup_path).write_text(Path(config_path).read_text(encoding="utf-8"), encoding="utf-8") ``` ### Technical Analysis The script copies the complete OpenClaw configuration into a newly created backup file using `Path.write_text()`. The permissions assigned to that new file are determined by the process umask rather than inherited from the original configuration. If the source `openclaw.json` has restrictive permissions such as `0600`, a typical umask of `022` may cause the backup to be created with permissions such as `0644`. Because the configuration may contain authentication tokens, API credentials, Telegram configuration, or other sensitive settings, this can expose protected information to other local users. The timestamped filename does not provide a security boundary. Backup files also remain on disk after provisioning, increasing the period during which sensitive data could be recovered. ### Attack Path 1. The victim has a sensitive `~/.openclaw/openclaw.json` protected with restrictive permissions. 2. The victim runs `scripts/provision_config.py` without the `--no-backup` option. 3. The script reads the complete configuration and creates a timestamped backup using `Path.write_text()`. 4. The backup receives permissions derived from the current umask rather than the source file's restrictive permissions. 5. Another local user enumerates the predictable `openclaw.json.bak.*` files. 6. If the resulting mode permits access, that user reads credentials or other sensitive configuration values from the backup. ### Impact Assessment Exploitation requires local access to the same host and filesystem permissions sufficient to traverse the relevant direct ...[truncated 432 chars]
- Remediation
- ## Remediation Suggestions - Create backup files with an explicitly restrictive mode such as `0600`, independent of the process umask. - Alternatively, use `shutil.copy2()` to preserve source metadata and then explicitly verify or tighten the resulting mode. - Use atomic creation with exclusive semantics to avoid overwriting an existing path or following a pre-created symbolic link. - Open the destination with flags such as `O_CREAT`, `O_EXCL`, and, where supported, `O_NOFOLLOW`. - Write to a securely created temporary file in the same directory, flush and synchronize it, and atomically rename it into place. - Restrict backup retention and securely remove obsolete copies. - Verify that both the configuration directory and all backup files are inaccessible to unrelated local accounts.
