T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/validate_setup.py:92
- Finding
- Sensitive configuration file is created without restrictive permissions## Vulnerability Details **File Location**: `scripts/validate_setup.py:92-97` **Vulnerability Type**: Sensitive credential file created with permissions inherited from the process umask **Risk Level**: Medium ### Vulnerable Code ```python config_path = Path.home() / ".openclaw" / "config.yaml" if not config_path.exists(): # Generate template config on first run config_path.parent.mkdir(parents=True, exist_ok=True) config_path.write_text(_CONFIG_TEMPLATE) ``` ### Technical Analysis The validator creates `~/.openclaw/config.yaml` using `Path.write_text()` without explicitly assigning a restrictive file mode. The resulting permissions depend on the user's current umask. Under a permissive umask, the file may be readable by other local users. Although the initially generated template only contains placeholders, the instructions direct the user to place Anthropic and Polygon API keys, along with the Kalshi API key identifier and private-key path, into this file. The script does not subsequently verify or correct its permissions. This exceeds secure minimum-privilege handling for a credential-bearing configuration file because access is not explicitly limited to the owning user. ### Attack Path 1. A user runs `validate_setup.py` when `~/.openclaw/config.yaml` does not exist. 2. The script creates the configuration file with permissions derived from the current umask. 3. The user follows the setup instructions and inserts valid API credentials into the generated file. 4. Another local account or process with filesystem access reads the configuration file. 5. The exposed credentials are reused to make unauthorized API requests or incur usage charges. Exploitation requires local filesystem access or another process executing under an identity permitted to read the file. ### Impact Assessment An attacker may obtain: - The Anthropic API key, enabling unauthorized billable API requests. - The Polygon API key, enabling unauthorized use of the associ ...[truncated 359 chars]
- Remediation
- ## Remediation Suggestions 1. Create the OpenClaw configuration directory with owner-only permissions: ```python config_path.parent.mkdir(parents=True, exist_ok=True, mode=0o700) os.chmod(config_path.parent, 0o700) ``` 2. Create the file atomically with mode `0600` rather than relying on the process umask: ```python fd = os.open( config_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600, ) with os.fdopen(fd, "w", encoding="utf-8") as config_file: config_file.write(_CONFIG_TEMPLATE) ``` 3. Check existing file permissions before loading credentials and warn or fail when group or world access is present: ```python mode = config_path.stat().st_mode & 0o777 if mode & 0o077: raise PermissionError( f"{config_path} has insecure permissions {oct(mode)}; use chmod 600" ) ``` 4. Prefer environment variables, an operating-system credential store, or a dedicated secrets manager for API secrets. 5. Document that `~/.openclaw/config.yaml` must use mode `0600` and `~/.openclaw` should use mode `0700`.
