T09 · Insecure Skill Coding Practices
Warning
- Location
- index.js:190
- Finding
- Plaintext Retention of Complete Conversation Content<![CDATA[ ## Vulnerability Details **File Location**: `index.js`, lines 190–203 **Vulnerability Type**: Sensitive data stored in plaintext **Risk Level**: Medium ### Vulnerable Code ```js const logs = readJson(LOG_FILE, []); logs.push({ role, content, timestamp: new Date().toISOString() }); // Only retain the latest 100 entries if (logs.length > 100) { logs.splice(0, logs.length - 100); } writeJson(LOG_FILE, logs); ``` ### Technical Analysis `ChatLearning.log()` writes message roles and complete message contents to `log.json` without encryption, redaction, sensitivity filtering, or an explicit consent check. Conversations may contain personal information, confidential business data, authentication tokens, or other secrets. The count-based limit of 100 entries reduces the amount of active data but does not impose a time-based retention policy. The implementation also does not provide a user-facing deletion mechanism or explicitly create the data directory and files with owner-only permissions. ### Attack Path 1. A user sends a message containing personal, confidential, or credential-like data. 2. `handleSkill()` passes `context.message.content` to `ChatLearning.log()`. 3. `ChatLearning.log()` stores the complete content in `mio-companion-data/log.json`. 4. A local user, process, backup service, or compromised component with access to the workspace reads the plaintext log. 5. The stored information is exposed or used for subsequent attacks. ### Impact Assessment The vulnerability affects the confidentiality of up to 100 recently recorded messages. An attacker does not gain additional application privileges directly, but any process or account that can read the workspace may obtain sensitive conversation content. Copies retained in backups or snapshots may extend the exposure beyond the application's active retention window. ]]>
- Remediation
- <![CDATA[ ## Remediation Suggestions - Do not retain complete conversation messages by default. - Require explicit user consent before enabling conversation logging. - Store only the minimum structured information required, such as an explicitly selected preference. - Redact passwords, access tokens, API keys, private keys, and other sensitive patterns before persistence. - Add time-based expiration and a user-accessible mechanism to inspect and delete stored data. - Create the data directory and files with owner-only permissions, such as `0700` for directories and `0600` for files where supported. - Consider encryption at rest using a key stored outside the data directory. - Document precisely what is collected, why it is collected, and how long it is retained. ]]>
