T09 · Insecure Skill Coding Practices
- Location
bt_common/config.py:151- Finding
API Tokens Stored Without Enforced Restrictive File Permissions
- Content
View full analysis
Vulnerability Details
File Location:
bt_common/config.py:151-162,bt_common/config.py:421-424
Vulnerability Type: Insecure storage of privileged API credentials
Risk Level: HighTechnical Analysis
The global configuration file contains aaPanel API tokens but is created and rewritten without explicitly enforcing owner-only permissions.
python if not GLOBAL_CONFIG_FILE.exists(): GLOBAL_CONFIG_FILE.write_text(default_config, encoding="utf-8") return GLOBAL_CONFIG_FILEServer additions subsequently rewrite the credential-bearing YAML file using the process's current umask:
python # Save config path = Path(config_path) with open(path, "w", encoding="utf-8") as f: yaml.dump( config, f, default_flow_style=False, allow_unicode=True, sort_keys=False, ) return TrueThe resulting permissions therefore depend on the runtime environment. Under a permissive umask or when a user-selected configuration path is used, the file may be readable by other local accounts. The implementation also does not verify that the file is owned by the current user before loading or rewriting it.
Attack Path
- A user adds an aaPanel server, causing its API token to be written to the YAML configuration.
- The configuration is created under a permissive umask, inherited permissions, or an inadequately protected custom path.
- Another local user or compromised process reads the file.
- The attacker extracts the aaPanel host and API token.
- The attacker uses the token to invoke the same privileged panel APIs exposed by the skill.
Impact Assessment
Exposure of the API token can grant access to all capabilities allowed by that aaPanel API credential. In this project, those capabilities include arbitrary remote file reads and writes, file deletion, recursive permission changes, site and certificate management, database and FT ...[truncated 143 chars]
- Remediation
View remediation
Remediation Suggestions
- Create the configuration atomically with mode
0600, such as by usingos.openwithO_CREAT | O_EXCLand an explicit mode. - Apply
chmod(0o600)after every rewrite and ensure~/.openclawis mode0700. - Write updates to a protected temporary file in the same directory and atomically replace the destination.
- Reject configuration files not owned by the current user or writable by group/others.
- Warn and refuse to proceed when existing permissions are broader than
0600. - Prefer an operating-system credential store or dedicated secret manager over plaintext YAML.
- Limit the aaPanel token to the minimum API permissions and source IPs required.
- Create the configuration atomically with mode
