-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Redact read_file content from UI storage #8692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…storing file contents in clineMessages (Fixes #8690)
Code Review CompleteI've completed a thorough review of this PR and found no issues that need to be addressed. SummaryThe implementation correctly prevents file contents from being stored in ✅ Sanitization methods properly redact file payload XML tags The PR successfully addresses issue #8690 and is ready to merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR redacts file contents from UI-persisted messages to prevent sensitive data from being stored in ui_messages.json, while preserving full content for the API conversation history.
- Adds sanitization helpers and applies them at append/update/overwrite/save/load of UI messages
- Redacts file payloads in api_req_started request formatting
- Updates e2e tests to validate via AI response rather than clineMessages
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.
File | Description |
---|---|
src/core/task/Task.ts | Introduces message sanitization and read_file redaction for UI-persisted messages and api_req_started formatting. |
apps/vscode-e2e/src/suite/tools/read-file.test.ts | Updates tests to reflect redaction; removes direct content checks from clineMessages (but leaves now-unused variables/extraction logic). |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
const formatRequestWithReadFileRedaction = (blocks: Anthropic.Messages.ContentBlockParam[]) => { | ||
let redactNext = false | ||
const parts = blocks.map((block: any) => { | ||
if (block?.type === "text") { | ||
const text = String(block.text ?? "") | ||
|
||
// 1) Detect the explicit read_file header line emitted by pushToolResult | ||
const isReadFileHeader = /^\[read_file\b[\s\S]*\]\s*Result:/i.test(text) | ||
|
||
// 2) Detect any XML-like file payloads that tools may include | ||
// Examples: <files>...</files>, <file>...</file>, <content ...>...</content>, <file_content ...>...</file_content> | ||
const looksLikeFilePayload = /<files[\s>]|<file[\s>]|<content\b|<file_content\b/i.test(text) | ||
|
||
// If we see the header, show the header but redact the next text block (payload) | ||
if (isReadFileHeader) { | ||
redactNext = true | ||
return text | ||
} | ||
|
||
// If the previous block was a read_file header, or this block itself looks like a file payload, redact it | ||
if (redactNext || looksLikeFilePayload) { | ||
redactNext = false | ||
return "[tool output omitted from UI storage]" | ||
} | ||
} | ||
|
||
// Default formatting for other blocks | ||
return formatContentBlockToMarkdown(block as any) | ||
}) | ||
return parts.join("\n\n") | ||
} |
Copilot
AI
Oct 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-redacted text blocks (including the read_file header) bypass formatContentBlockToMarkdown and return raw text, which diverges from prior behavior and from how non-text blocks are formatted. To keep formatting consistent and avoid UI regressions, return formatContentBlockToMarkdown(block) for the non-redacted text path (and for the header), e.g., replace return text with return formatContentBlockToMarkdown(block as any).
Copilot uses AI. Check for mistakes.
let errorOccurred: string | null = null | ||
let toolExecuted = false | ||
let toolResult: string | null = null | ||
let _toolResult: string | null = null |
Copilot
AI
Oct 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_toolResult is never read after assignment in this test. Remove this variable and the associated extraction/logging code to reduce noise and keep the test focused on verifying AI responses.
let _toolResult: string | null = null |
Copilot uses AI. Check for mistakes.
if (resultMatch) { | ||
toolResult = resultMatch[1] | ||
console.log("Extracted tool result:", toolResult) | ||
_toolResult = resultMatch[1] | ||
console.log("Extracted tool result:", _toolResult) | ||
} else { | ||
console.log("Could not extract tool result from request") | ||
} |
Copilot
AI
Oct 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This extraction/logging block sets _toolResult but the value is no longer asserted, making it dead code. Remove the extraction and console logs to simplify the test.
Copilot uses AI. Check for mistakes.
let toolResult: string | null = null | ||
let _toolResult: string | null = null | ||
|
||
// Listen for messages |
Copilot
AI
Oct 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_toolResult is declared but never used in this test case. Remove the variable and the related parsing code added for it.
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
Closed in favour of #8696 |
Before


After



This PR prevents file contents returned by read_file and mention expansions from being stored in ui_messages.json.\n\n- Sanitizes UI-persisted messages at append/update/overwrite/save/load\n- Redacts api_req_started request so file payloads never land in clineMessages
Fixes #8690
Fixes #5601
Fixes #8594
Important
Redacts file contents from UI storage in
Task.ts
by sanitizing messages, ensuring sensitive data is not stored inui_messages.json
.Task.ts
by sanitizing messages before saving toui_messages.json
.sanitizeMessageText()
andsanitizeMessagesArray()
to handle redaction.addToClineMessages()
,overwriteClineMessages()
,updateClineMessage()
, andsaveClineMessages()
to use sanitization.api_req_started
requests to prevent file payloads from being stored inclineMessages
.read-file.test.ts
to remove assertions on file content extraction.toolResult
to_toolResult
inread-file.test.ts
and 2 other places.This description was created by
for 0377592. You can customize this summary. It will automatically update as commits are pushed.