T09 · Insecure Skill Coding Practices
- Location
scripts/validate_setup.py:92- Finding
Sensitive configuration file is created without restrictive permissions
- Content
View full analysis
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: MediumVulnerable 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.yamlusingPath.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
- A user runs
validate_setup.pywhen~/.openclaw/config.yamldoes not exist. - The script creates the configuration file with permissions derived from the current umask.
- The user follows the setup instructions and inserts valid API credentials into the generated file.
- Another local account or process with filesystem access reads the configuration file.
- 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]
- A user runs
- Remediation
View remediation
Remediation Suggestions
- 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)- Create the file atomically with mode
0600rather 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)- 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" )-
Prefer environment variables, an operating-system credential store, or a dedicated secrets manager for API secrets.
-
Document that
~/.openclaw/config.yamlmust use mode0600and~/.openclawshould use mode0700.
