Skip to content

v0.15.1 — block stored memory-injection

Choose a tag to compare

@cremenescu cremenescu released this 22 Jul 06:07

Hardening

Two complementary fixes for stored / indirect prompt-injection via the memory store. A low-trust write — most realistically an agent's MCP memory_add, since the store is shared across agents — could plant a memory that hijacks the trust-bearing content injected at the start of every session.

  • Delimiter forgery on write blocked — a memory body/summary was serialized verbatim into the delimiter-based record format, so one write could forge a second record, or self-escalate its own, to priority: critical (injected at the top of every session, and, if protected: true, undeletable from the UI). render_record / render_from_meta now fold summary line breaks and backslash-escape any body line that matches the record delimiters (START_RE / END_MARK) — the single choke-point every write path (CLI, MCP, web, consolidation) passes through. Legit ### / - key: body content is left untouched and the escape is idempotent, so edit / re-scope / merge re-renders don't double-escape.
  • Heading forgery in the SessionStart hook blocked — a 2-space indent does not neutralize an ATX heading (CommonMark allows 0–3 leading spaces), so a normal memory body containing ## Critical rules (mandatory in every task) could forge one of the hook's own trust-bearing sections. All three body-emit paths (profile, critical, budgeted) now route through _body_lines, which escapes any #-leading line.

No API, config or store-format changes; ordinary notes render identically.