feat(core): scrub leaked tool-call wire-format at the capture boundary - #63
Open
widgetii wants to merge 2 commits into
Open
feat(core): scrub leaked tool-call wire-format at the capture boundary#63widgetii wants to merge 2 commits into
widgetii wants to merge 2 commits into
Conversation
kaeru is an MCP server whose callers are arbitrary LLMs; a malformed tool call can spill the invocation envelope (`<parameter name="...">`, `</parameter>`, an invoke wrapper) into a string argument and get stored verbatim, polluting the graph. Since the server can't control how a model formats a call, it now defends at the write boundary. New `kaeru_core::sanitize::strip_tool_call_markup` removes a leaked envelope. It is deliberately NARROW — keyed to the specific tool-call markers (matching plain and `antml:`-namespaced spellings), never angle-bracket markup in general — so legitimate content (`Vec<u8>`, XML snippets, a literal `</body>` in prose) passes through untouched. Applied inside the write primitives (`cite`, `write_episode`, `jot`, `improve`) so every adapter gets clean storage, not just MCP. The MCP capture/revise handlers surface a `(note: stripped leaked tool-call markup from ...)` line so the caller knows sanitization happened. Tests: sanitizer unit tests (observed leak, namespaced form, trailing close tag, wholly-envelope, and legitimate-markup preservation) plus a cite wiring test asserting the stored body is scrubbed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> (cherry picked from commit 55bd449d1c5d9f4cbf3bac2c9549c832b4bb64bd)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
kaeru is an MCP server; its callers are arbitrary LLMs and it has no
control over how a model formats a tool call. A malformed call can spill
the invocation envelope — the parameter open/close tags, an invoke
wrapper — into a string argument (
name/body), and kaeru stored itverbatim. Observed in the field: a
citebody ended with…not a firmware toggle.</body>\n<parameter name="initiative">rack, andbecause the
initiativecollapsed into the body text the node alsolanded un-scoped.
Treating whatever arrives as trusted is the server's bug, not the
caller's.
Fix
New
kaeru_core::sanitize::strip_tool_call_markupremoves a leakedenvelope at the write boundary. It is deliberately narrow — keyed
to the specific tool-call markers (matching both plain and
antml:-namespaced spellings), never angle-bracket markup in general —so legitimate content survives untouched: code (
Vec<u8>), XML/HTMLsnippets, even a literal
</body>in prose. High precision: it onlyfires on an actual leak.
Applied inside the write primitives —
cite,write_episode,jot,improve— so every adapter (MCP, rig, cloud ingest) gets cleanstorage, not just one. The MCP capture/revise handlers add a
(note: stripped leaked tool-call markup from …)line so the caller istold sanitization happened (policy: strip + flag, not silent, not reject).
Tests
tag, wholly-envelope → empty, and legitimate-markup preservation
(code / comparisons / HTML-ish tags pass through unchanged).
citewiring test: a dirty body is stored scrubbed.kaeru-core 140 green, kaeru-mcp 20 green. Independent of #61/#62 (no
substrate/schema change).
🤖 Generated with Claude Code