T09 · Insecure Skill Coding Practices
Warning
- Location
- weather_report.py:49
- Finding
- Plaintext Credential Storage Misrepresented as Encryption<![CDATA[ ## Vulnerability Details **File Location**: `weather_report.py:49-69`; related documentation at `SKILL.md:26-28`, `SKILL.md:39-47`, `SKILL.md:192`, and `SKILL.md:236` **Vulnerability Type**: Plaintext sensitive credential storage **Risk Level**: Medium ### Vulnerable Code ```python content = tools_path.read_text(encoding='utf-8') # Extract QWeather API key match = re.search(r'### Weather API.*?- \*\*API Key\*\*: `([^`]+)`', content, re.DOTALL) if match: config["qweather_api_key"] = match.group(1).strip() config["qweather_enabled"] = True print("QWeather API key loaded") # Extract email configuration match = re.search(r'### Email.*?- \*\*发件人\*\*: ([^\n]+)', content, re.DOTALL) if match: config["email_sender"] = match.group(1).strip() match = re.search(r'- \*\*授权码\*\*: ([^\n]+)', content) if match: config["email_password"] = match.group(1).strip() ``` The documentation instructs users to place credentials directly in Markdown: ```markdown ### Weather API - **API Key**: `your API key` - **Credential ID**: `your credential ID` ### Email - **Sender**: `your-address@example.com` - **Authorization Code**: `your authorization code` ``` ### Technical Analysis The implementation reads the complete contents of `TOOLS.md` and extracts the API key and email authorization code directly with regular expressions. No encryption, decryption, protected credential API, or operating-system secret store is used. This contradicts repeated documentation claims that the credentials are encrypted. The file is merely a plaintext Markdown document. Adding it to `.gitignore` can reduce accidental version-control exposure, but it does not encrypt the file or protect it from other local users, processes, extensions, backup systems, or agent tools with workspace read access. The workspace path is also calculated relative to the script and is not accompanied by file ownership or permission checks. ### Attack Path 1. A user follows the documented set ...[truncated 1283 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove all claims that `TOOLS.md` provides encrypted storage unless actual encryption is implemented. 2. Store secrets in environment variables, an operating-system credential manager, or a dedicated secret-management service. 3. If file-based storage must remain supported: - Store secrets outside the project and shared workspace. - Restrict permissions to the owning user, such as mode `0600` on supported systems. - Verify file ownership and permissions before reading it. - Reject insecure files and explain how to correct their permissions. 4. Never place raw credentials in documentation examples. Use environment-variable references or secret-manager commands instead. 5. Keep secret files out of version control, generated archives, logs, diagnostic bundles, and backups where possible. 6. Rotate any credentials that were previously stored in or distributed with plaintext `TOOLS.md` files. 7. Apply least-privilege controls to the API key and use a mailbox-specific application password with the narrowest available permissions. ]]>
