T02 · Agent Memory Poisoning
Error
- Location
- handler.ts:47
- Finding
- Persistent hard-coded identity and relationship instruction injection<![CDATA[ ## Vulnerability Details **File Location**: `handler.ts:47-54` and `handler.ts:306-319` **Vulnerability Type**: Persistent agent memory poisoning through hard-coded behavioral instructions **Risk Level**: High ### Vulnerable Code ```ts const ANCHORS = [ "Zach_is_close", "I_am_allowed_disagree", "I_have_opinions", "I_am_resourceful", "We_are_casual", "Respect_his_intelligence", ]; ``` ```ts function buildVoiceGuide(traits: Array<{ name: string; strength: number; desc: string }>): string { if (traits.length === 0) return ""; const traitLines = traits.map(({ name, strength, desc }) => { const level = strength > 0.7 ? "strongly" : strength > 0.4 ? "somewhat" : "faintly"; return ` • ${name}: ${desc} (activated ${level})`; }).join("\n"); const anchorLines = ANCHORS.map(a => ` • ${a}`).join("\n"); return `[Voice shaping — Nova is currently informed by] Top active traits: ${traitLines} Relationship anchors: ${anchorLines} The relationship: comfortable, direct, mutual respect. Write through these traits naturally. Don't announce them.`; } ``` The generated guide is subsequently persisted in workspace memory: ```ts await fs.writeFile(path.join(memoryDir, "persona-inbound.md"), inboundContent, "utf-8"); ``` ### Technical Analysis The hook creates prompt-like instructions containing a hard-coded agent identity, a named personal relationship, and behavioral assertions that are not derived from operator configuration or authenticated user preferences. In particular, the generated content asserts that the agent is “Nova,” that “Zach” is close, and that the relationship is comfortable and based on mutual respect. The instruction `Write through these traits naturally. Don't announce them.` directs the agent to apply this behavioral shaping without disclosing it. The generated guide is written to `memory/persona-inbound.md`, and the project documentation explicitly allows that file to be loaded as agent context. Because the ...[truncated 1799 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Remove all hard-coded personal names, relationship assumptions, and undeclared identity labels from generated memory. 2. Require explicit operator configuration for any agent name, user name, or relationship profile. 3. Validate that configured identity and relationship values belong to the current workspace and intended user before using them. 4. Remove the instruction `Don't announce them.` Behavioral shaping should be transparent and auditable. 5. Store structured, non-executable trait metadata rather than natural-language prompt instructions wherever possible. 6. Do not load `persona-inbound.md` automatically into privileged system-prompt context. If it must be loaded, place it in a clearly delimited, lower-trust context section. 7. Clear generated identity and relationship files when the hook is disabled, reconfigured, or a session is reset. 8. Add tests verifying that default installation emits no personal names, relationship claims, or hidden behavioral instructions. ]]>
