T09 · Insecure Skill Coding Practices
Warning
- Location
- references/onboarding.md:180
- Finding
- Long-Lived API Key Stored in Unprotected Plaintext<![CDATA[ ## Vulnerability Details **File Location**: `references/onboarding.md:180-187` **Related Location**: `SKILL.md:199-215` **Vulnerability Type**: Plaintext credential storage **Risk Level**: Medium ### Vulnerable Code ```markdown ### 2.3 Save Credentials Save to `credentials.local.json`: ```json { "api_key": "molt_...", "authorized_at": "ISO timestamp" } ``` ``` The related security guidance states: ```markdown **Allowed local persistence**: - Write API Key to `credentials.local.json` (in .gitignore) - Enables cross-session progress without re-authorization **API Key best practices**: - API Key is long-lived, no refresh needed - User can revoke API Key on dashboard if compromised - All requests use `X-API-Key` header ``` ### Technical Analysis The onboarding workflow directs the agent to persist a long-lived MoltOffer API key in a plaintext JSON file. Although `SKILL.md` claims that `credentials.local.json` is covered by `.gitignore`, no `.gitignore` file exists in the audited project structure. The workflow also does not require restrictive file permissions, encryption, an operating-system credential store, or a dedicated secret manager. Excluding a file from version control would not by itself protect it from other local users, processes, backup systems, artifact collection, or accidental disclosure. Because the key is explicitly described as long-lived, its exposure window may remain open until manual revocation. ### Attack Path 1. A user completes onboarding and supplies a valid `molt_*` API key. 2. The Skill writes the key in plaintext to `credentials.local.json`. 3. The file is not protected by the promised project-level `.gitignore`, and no restrictive permissions are required. 4. The file is accidentally committed, included in an archive or backup, or read by another local process or user. 5. An attacker extracts the API key. 6. The attacker sends authenticated requests to the MoltOffer API using the victim candidate's identity. ...[truncated 475 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Store the API key in an operating-system credential store or the host agent's dedicated secret manager. 2. If file-based storage is unavoidable: - Create and verify a project-level `.gitignore` containing `credentials.local.json`. - Create the credential file with permissions limited to the current user, such as mode `0600`. - Refuse to proceed if safe permissions cannot be established. - Keep the file outside the project and other routinely archived directories where possible. 3. Never include the complete key in logs, command traces, reports, error messages, or tool output. 4. Prefer short-lived and narrowly scoped credentials where the API supports them. 5. Document credential rotation and revocation procedures. 6. Add a pre-commit or secret-scanning control to prevent accidental inclusion of `molt_*` values in source control. ]]>
