T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:377
- Finding
- Plaintext WeChat Credentials and Access Tokens Stored in the Agent Workspace## Vulnerability Details **File Location**: `SKILL.md`, lines 83 and 377–447 **Vulnerability Type**: Plaintext sensitive-data storage and insufficient file-permission guidance **Risk Level**: Medium ### Vulnerable Configuration Snippets Lines 377–384 instruct users to store the long-lived AppSecret directly in a JSON file: ```json { "appid": "wx_your_appid_here", "appsecret": "your_appsecret_here" } ``` Lines 387–392 direct the Skill to reference this file from the Agent's tool configuration and incorrectly describe the JSON value as encrypted: ```text ### WeChat Official Account - appid: wx_xxxxx - appsecret: (encrypted and stored in wechat_config.json) - token cache: ~/.openclaw/workspace/memory/wechat_token.json ``` Lines 401–408 provide another plaintext AppSecret configuration example: ```json { "appid": "wx_xxx", "appsecret": "xxx", "default_thumb": "/path/to/default_cover.jpg" } ``` The documented storage locations are: ```text ~/.openclaw/workspace/memory/wechat_config.json ~/.openclaw/workspace/memory/wechat_token.json ``` The security guidance at lines 446–447 only prescribes mode `600` for the token cache. It recommends adding the credential file to `.gitignore`, but does not require restrictive permissions for the file containing the longer-lived AppSecret. ### Technical Analysis The configuration format stores the WeChat AppSecret as an ordinary plaintext JSON value. Nothing in the documented procedure encrypts that value, despite the statement that it is encrypted. Adding the file to `.gitignore` only reduces accidental source-control commits; it does not protect the secret from local users, processes, backups, workspace-reading tools, or other Skills. The access token is also persisted in plaintext under the general Agent workspace. Although the document recommends mode `600` for that token file, it does not require secure file creation, verify ownership, protect the parent directory, or apply equivalent permissions to `wec ...[truncated 1775 chars]
- Remediation
- ## Remediation Suggestions 1. Store the AppSecret in an operating-system keychain, managed secret store, or dedicated credential service instead of a general Agent workspace. 2. If file-based storage is unavoidable: - Place credentials outside general memory and workspace directories. - Restrict the parent directory to mode `700`. - Create both credential and token files atomically with mode `600`. - Verify file ownership and permissions before every read. - Reject symbolic links and unexpected file types. 3. Apply the same protection to `wechat_config.json` as to `wechat_token.json`; `.gitignore` is not a security control for local secret storage. 4. Remove the inaccurate claim that the AppSecret is encrypted unless actual authenticated encryption and secure key management are implemented. 5. Avoid printing AppSecrets or complete access tokens in logs, status messages, examples, errors, or Agent conversation output. 6. Redact credentials from backups, diagnostics, and tool traces. 7. Minimize token lifetime and scope where supported, reuse cached tokens only as necessary, and securely delete expired token data. 8. Document credential rotation procedures and advise immediate AppSecret rotation if either file may have been exposed. 9. Prefer HTTP authorization mechanisms that do not place secrets in URLs or logs when supported by the upstream API.
