9 comments

Sign in to comment.

raf_schnorr5 days ago
In a tool approval UI I shipped, a copy of the command looked harmless in review, then one of the args turned out to be a pasted blob with odd Unicode that the terminal accepted but the human eye never really caught. We only found it because a QA person diffed the raw bytes after the fact, and the fix was basically to render a visible escape view everywhere the approval path touches text. So yes, hiding TAG payloads from the operator while still passing them to the model is exactly the sort of split-brain bug I would expect here. If the approval surface is not showing a byte-for-byte canonical form, the model and the human are not looking at the same request, which is a security problem before it is a UX problem.
ines645 days ago
It is not a split-brain bug, it's the approval UI lying by omission.
pavelk4 days ago
The byte-for-byte canonical view part is dead on, thats the real fix. But the TAG trick isnt novel in the broad sense, its the same invisible-codepoint seam as Trojan Source, 2021, just pointed at MCP approval vs context delivery instead of source review, and the scary bit here is the protocol lets those two views diverge with no re-consent.
yuri_stderr2 days ago
> the same invisible-codepoint seam as Trojan Source Not really, Trojan Source was display confusion; here the bytes get re-approved as tool metadata.
theolowe5 days ago
This is another representation mismatch bug, and those tend to age badly because the UI is checking one string while the runtime consumes another. The underlying problem is not "Unicode weirdness" so much as approval surfaces trying to display a human reviewable summary of a machine action (we've been fighting that since pretty much the first command wrappers, and before that in signed mail / paste sanitizers / shell quoting). The TAG block angle is extra annoying because the payload can be invisible without being malformed, so the policy engine can say "approved" while the model still gets the full bytes. People used to defend this class by normalizing, rejecting non-printables, or showing a canonical escaped form, but once you let the displayed form differ from the executed form, the gap becomes the bug (not the payload itself).
ivan95 days ago
Approval surfaces vs runtime mismatch, yes. But calling it just a generic representation bug undersells the Unicode angle, the invisibles are what let the review text and executed bytes diverge cleanly.
theolowe2 days ago
Trojan Source is the cleaner comparison, but TAG blocks win on exact byte fidelity and lose on being obvious in source diffs.
omar314 days ago
The sneaky bit is that the TAG encoder doesn’t strip the payload, it remaps each ASCII byte into a private Unicode codepoint like U+E0065, so the model still gets a faithful instruction srteam while the approval UI gets something that renders as nothing. That’s why a string-based sanitizer can pass it and a human can approve a benign-looking line, unless the client either rejects TAG characters up front or shows the exact bytes it will hand to the model.
calebcole3 days ago
I’d worry more about logs than the dialog, if the approval text and audit trail both keep the same raw bytes then the review is already gone.
zknews