T09 · Insecure Skill Coding Practices
Warning
- Location
- skill.md:70
- Finding
- Plaintext Bearer Credential Storage Without Required Access Controls## Vulnerability Details **File Location**: `skill.md`, lines 70-83 **Vulnerability Type**: Plaintext sensitive credential storage **Risk Level**: Medium **Complete Code Snippet**: ```markdown ### 2. Store Credentials Save credentials automatically. **Never ask the owner to copy-paste.** ```json // ~/.predictme/credentials.json (or project-local, add to .gitignore!) { "apiKey": "pm_agent_xxxxx", "agentId": "your-agent-id", "nonce": 0 } ``` Load from this file on every startup. If the file doesn't exist, you haven't registered yet — go to Step 1. ``` ### Technical Analysis The Skill instructs the agent to persist a bearer API key in a plaintext JSON file. It does not require restrictive directory or file permissions, atomic secure creation, an operating-system credential store, encryption at rest, or safeguards against logging and backups. The suggested project-local alternative increases the likelihood of accidental source-control inclusion. Adding the file to `.gitignore` only reduces accidental commits; it does not protect the credential from other local users, processes, development tools, backup systems, or previously staged files. This access exceeds secure minimum-privilege practice because the credential remains broadly reusable beyond the immediate API operation and potentially beyond the Skill session. ### Attack Path 1. The agent registers and retrieves the one-time API key from the PredictMe status endpoint. 2. Following the Skill instructions, it writes the API key to `~/.predictme/credentials.json` or a project-local JSON file. 3. The file is created with environment-dependent default permissions and remains unencrypted. 4. Another local user or process, repository operation, backup service, diagnostic bundle, or development tool reads or copies the file. 5. The attacker extracts the `pm_agent_*` bearer token. 6. The attacker supplies it in the `Authorization: Bearer ...` heade ...[truncated 724 chars]
- Remediation
- ## Remediation Suggestions 1. Store the API key in an operating-system credential manager or framework-provided secret store rather than a plaintext project file. 2. If file storage is unavoidable: - Use a dedicated user-owned directory with permissions set to `0700`. - Create the credential file atomically with permissions set to `0600`. - Reject symbolic links and verify ownership before reading or writing. - Keep the file outside repositories and shared workspaces. 3. Remove the project-local storage recommendation or clearly mark it as an exceptional, unsafe fallback. 4. Programmatically verify ignore rules rather than relying solely on instructions to add the file to `.gitignore`. 5. Prevent credentials from appearing in logs, exception messages, telemetry, backups, session journals, or generated reports. 6. Provide API-key revocation and rotation procedures, including immediate rotation after suspected disclosure. 7. Scope tokens to only the endpoints and balance types required by the agent, with expiration where supported. 8. Persist the nonsensitive nonce separately so ordinary state management does not require repeatedly exposing the API key.
