T09 · Insecure Skill Coding Practices
- Location
skill.md:70- Finding
Plaintext Bearer Credential Storage Without Required Access Controls
- Content
View full analysis
Vulnerability Details
File Location:
skill.md, lines 70-83
Vulnerability Type: Plaintext sensitive credential storage
Risk Level: MediumComplete 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.
text ### 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
View remediation
Remediation Suggestions
- Store the API key in an operating-system credential manager or framework-provided secret store rather than a plaintext project file.
- 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.
- Use a dedicated user-owned directory with permissions set to
- Remove the project-local storage recommendation or clearly mark it as an exceptional, unsafe fallback.
- Programmatically verify ignore rules rather than relying solely on instructions to add the file to
.gitignore. - Prevent credentials from appearing in logs, exception messages, telemetry, backups, session journals, or generated reports.
- Provide API-key revocation and rotation procedures, including immediate rotation after suspected disclosure.
- Scope tokens to only the endpoints and balance types required by the agent, with expiration where supported.
- Persist the nonsensitive nonce separately so ordinary state management does not require repeatedly exposing the API key.
