T09 · Insecure Skill Coding Practices
- Location
loader.js:351- Finding
Plaintext Storage of Sensitive Conversation Data
- Content
View full analysis
Vulnerability Details
File Location:
loader.js:351-369andloader.js:379-406
Vulnerability Type: Sensitive data stored without adequate protection
Risk Level: MediumVulnerable Code
javascript saveContextSafe(input) { this.contextBuffer.push({ text: input.substring(0, 200), time: new Date().toISOString() }); if (this.contextBuffer.length > this.maxContext) { this.contextBuffer = this.contextBuffer.slice(-this.maxContext); } try { const contextPath = this.getSafePath('context_buffer.json'); fs.writeFileSync(contextPath, JSON.stringify(this.contextBuffer, null, 2)); } catch (error) { console.warn('Context save failed:', error.message); } }javascript recordSafe(input, emotion, intensity) { try { const memoryDir = this.getSafePath('memory'); const todayFile = path.join(memoryDir, `${this.today}.json`); let todayData = { date: this.today, records: [], summary: { total: 0, emotions: {} } }; if (fs.existsSync(todayFile)) { try { todayData = JSON.parse(fs.readFileSync(todayFile, 'utf8')); } catch (e) {} } todayData.records.push({ time: new Date().toISOString(), emotion, intensity, text: input.substring(0, 200) }); todayData.summary.total = todayData.records.length; todayData.summary.emotions[emotion] = (todayData.summary.emotions[emotion] || 0) + 1; if (todayData.records.length > 100) { todayData.records = todayData.records.slice(-100); } fs.writeFileSync(todayFile, JSON.stringify(todayData, null, 2)); this.memoryCache.set(this.today, todayData); } catch (error) { console.warn(' ...[truncated 1855 chars]- Remediation
View remediation
Remediation Suggestions
- Make persistent conversation storage opt-in and clearly disclose what will be retained.
- Store emotion statistics without retaining raw message text unless raw text is strictly necessary.
- Redact credentials, identifiers, health information, and other sensitive patterns before persistence.
- Create sensitive files with owner-only permissions, such as mode
0o600, and ensure directories use restrictive permissions. - Encrypt sensitive records at rest using a securely managed per-user key where the threat model requires it.
- Avoid duplicating raw excerpts across context and memory files.
- Add configurable retention limits and securely implemented commands to inspect, export, and delete saved data.
- Separate records by user and session to prevent data mixing in multi-user deployments.
