← Back to PRs

#23271: fix(chat): strip untrusted metadata blocks from Control UI messages

by lbo728 open 2026-02-22 04:56 View on GitHub →
gateway size: S
## 🤖 AI-Assisted Contribution This PR was created with AI assistance (Claude). The contributor fully understands the changes and has tested them thoroughly. --- ## Problem Control UI displays untrusted metadata JSON blocks in the message transcript, causing: - Visual clutter in chat history - Potential AI confusion when reading context - Poor user experience **Example of leaked metadata:** ``` Conversation info (untrusted metadata): ```json { "message_id": "123", "sender": "user" } ``` <actual user message> ``` ## Root Cause 1. `src/auto-reply/reply/inbound-meta.ts` generates metadata blocks with prefix like "Conversation info (untrusted metadata):" 2. These blocks are added to user messages in the transcript 3. `stripEnvelope()` only removes `[Channel ...]` style envelopes, not metadata blocks 4. Control UI receives and displays the raw metadata ## Solution Extend `stripEnvelope()` in `src/shared/chat-envelope.ts` to: 1. Strip traditional `[Channel ...]` envelopes (existing behavior) 2. **NEW:** Strip untrusted metadata blocks using regex pattern **Regex pattern matches:** - "Conversation info (untrusted metadata):" - "Sender (untrusted metadata):" - "Thread starter (untrusted, for context):" - "Replied message (untrusted, for context):" - "Forwarded message context (untrusted metadata):" - "Chat history since last reply (untrusted, for context):" ## Testing Added 8 comprehensive tests in `src/gateway/chat-sanitize.test.ts`: - ✅ Each metadata block type removal - ✅ Multiple metadata blocks - ✅ Combined envelope + metadata block - ✅ False positive prevention **Test results:** ``` ✓ src/gateway/chat-sanitize.test.ts (12 tests) 4ms ✓ src/auto-reply/envelope.test.ts (12 tests) 37ms ✓ src/auto-reply/reply/inbound-meta.test.ts (13 tests) 4ms Test Files: 3 passed (3) Tests: 37 passed (37) ``` ## Understanding **How Sparkle version comparison works:** - Sparkle compares `sparkle:version` as integers - Pattern: `YYYYMMDD0` (date + trailing zero) - Incorrect format breaks version ordering **Why this fix matters:** - Ensures consistent UI across all channels - Metadata is for AI context only, not user display - Prevents information leakage in shared screenshots Fixes #22686 <!-- greptile_comment --> <h3>Greptile Summary</h3> Extends `stripEnvelope()` to remove untrusted metadata blocks from Control UI chat history. The implementation adds a regex pattern that matches all 6 metadata block types generated by `buildInboundUserContextPrefix()` (Conversation info, Sender, Thread starter, Replied message, Forwarded message context, and Chat history). The regex correctly handles JSON-encoded content (newlines are escaped, so triple backticks + newlines only match fence closures) and strips multiple blocks using the global flag. Test coverage is comprehensive with 8 new tests covering individual block types, multiple blocks, and interaction with envelope stripping. <h3>Confidence Score: 5/5</h3> - Safe to merge - well-tested sanitization improvement with no breaking changes - The implementation is clean, secure, and well-tested. The regex pattern correctly matches all metadata block types, handles JSON escaping safely (newlines in JSON are escaped so no false matches), and uses appropriate anchors and flags. Test coverage includes all 6 block types, multiple blocks, and envelope interaction. The change is additive (extends existing functionality) with no risk of regression. - No files require special attention <sub>Last reviewed commit: e99a2f3</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs