T02 · Agent Memory Poisoning
- Location
src/archiver.ts:101- Finding
Untrusted Transcript Content Is Persisted in Agent Memory Without Sanitization
- Content
View full analysis
= []; let skipped = 0; for (const file of files) { try { const content = await fs.readFile(file, 'utf8'); const lines = content.split('\n').filter(l => l.trim()); for (const line of lines) { try { const msg = JSON.parse(line) as TranscriptMessage; if (msg.type !== 'message' || !msg.message) continue; // Parse UTC timestamp and convert to local const utc = new Date(msg.timestamp); const local = new Date(utc.getTime() + (utc.getTimezoneOffset() * 60000)); if (local >= startOfDay && local < endOfDay) { const textObj = msg.message.content.find(c => c.type === 'text'); if (textObj?.text) { messages.push({ role: msg.message.role, text: textObj.text, time: local }); } } } catch { skipped++; } } } catch { // Skip unreadable files } } ``` ```typescript for (const msg of messages) { for (const kw of keywords) { if (msg.text.toLowerCase().includes(kw.toLowerCase())) { const snippet = msg.text.substring(0, Math.min(80, msg.text.length)) + (msg.text.length > 80 ? '...' : ''); highlights.push({ role: msg.role, snippet }); break; // only first keyword per message } } } ``` ```typescript const highlightsText = daily.highlights.length > 0 ? daily.highlights.map(h => `- ${h.role === 'user' ? 'User' : 'Asst'}: ${h.snippet}`).join('\n') : 'No highlights'; const template = this.config.templates.dailyLog; return template .replace(/{date}/g, daily.date) .replace(/{userCount}/g, String(daily.userC ...[truncated 2449 chars]- Remediation
View remediation
