T09 · Insecure Skill Coding Practices
Warning
- Location
- SKILL.md:29
- Finding
- Plaintext Persistence of the ComPDF API Key## Vulnerability Details **File Location**: `SKILL.md`, lines 29–38 **Vulnerability Type**: Plaintext sensitive credential storage **Risk Level**: Medium ### Vulnerable Code Snippet ```markdown ### Step 1 — Obtain API Key Check whether `config/public_key.txt` exists and contains a non-empty value. - **If the file exists and is non-empty**: use the stored key (trim whitespace). - **If the file is missing or empty**: ask the user for their ComPDF API Public Key. Inform them it can be obtained at <https://www.compdf.com/compdf-portal/signin?utm_source=clawhub&utm_medium=skillhub&utm_campaign=pdf_skill_md_convert&ref_platform_id=clawhub_skills>. After the user provides the key, ask whether they would like to save it locally for future sessions. - If the user agrees, write the key to `config/public_key.txt`. - If the user declines, use the key for the current session only without saving. > The key file is **not included in the published skill package**. It is created at runtime only when the user explicitly opts in. The user may delete `config/public_key.txt` at any time to revoke local storage. ``` The insecure storage behavior is reiterated in `SKILL.md`, line 167: ```markdown 7. **User-controlled API Key storage** — the key file (`config/public_key.txt`) is never shipped with the skill package. It is created at runtime only when the user explicitly opts in. The user may delete it at any time. ``` ### Technical Analysis The Skill instructs the Agent to persist an API authentication credential directly in `config/public_key.txt`. Although persistence requires user consent, the instructions do not require encryption, owner-only filesystem permissions, use of an operating-system credential store, exclusion from version control, or protection from backups and diagnostic collection. Consent determines whether storage occurs but does not make the resulting plaintext storage secure. Depending on the runtime environment and default file-creation mask, the ke ...[truncated 1547 chars]
- Remediation
- ## Remediation Suggestions 1. Prefer an operating-system credential store or dedicated secret manager instead of a project-local plaintext file. 2. If file-based storage is unavoidable: - Create the file atomically with owner-only permissions, such as mode `0600`. - Ensure the containing directory is accessible only to the owning user, such as mode `0700`. - Refuse to use the file if ownership or permissions are unsafe. - Avoid following symbolic links when creating or reading the file. 3. Add `config/public_key.txt` or the entire runtime `config/` directory to `.gitignore` and equivalent packaging exclusions. 4. Clearly warn the user that file-based persistence stores the credential locally and may expose it through backups, archives, or repository commits. 5. Never include the API key in logs, command output, error messages, telemetry, or generated reports. 6. Support credential deletion and rotation, and direct users to revoke a key immediately if exposure is suspected. 7. Prefer session-only credential use as the secure default, making persistence an explicit secondary option.
