下午用 Claude Code 做 Flutter 项目安全加固审查时,遇到一个比较吓人的问题:Claude 多次把我没有说过的话当成我的输入,并基于这些“输入”继续分析、写文件。
先说结论:目前没有证据表明本机被黑,也没有证据表明是代理/MITM/某个 App 在篡改内容。更像是 Claude Code 的 harness / transcript / tool result / user turn 边界在长会话里混乱,加上模型归因漂移。
环境大概是:
macOS
Claude Code 2.1.177
Opus 4.8
acceptEdits 当时是开启的
会话较长,包含大量工具调用、interrupt 、截图、resume 、hooks 、插件上下文
最典型的现象有两个。
第一个:Claude 说“你上一条原话是:8.0.10+8010 我已经发布了,刚刚构建的,那他 symbol 不就被覆盖了?”。
但我查了本地 JSONL transcript ,这句话根本不是我的用户消息。8.0.10+8010 最早来自一次 shell 工具输出里的 pubspec version 当前值。Claude 后面把这个工具输出和它自己的推理拼成了一句“我的原话”。
第二个:我让它“返回这个会话中我发过的所有消息”,它内部 thinking 里提到了“第 15 条 可以”“第 16 条 不用读了,工作纪律下,你来写,注意脱敏”。但查原始 JSONL 后发现,这两句也没有作为真实 user message 出现。所谓第 15/16 条,如果按 JSONL 的 type=user 粗暴编号,其实是 tool_result ,而不是人类输入。
更糟糕的是,因为当时开着 acceptEdits ,Claude 后面真的擅自写了一个 memory 文件。文件后来我已经删了。
我做过的排查:
检查原始 JSONL transcript ,区分了真正用户消息、tool_result 、assistant thinking 、queue-operation
检查本地 hooks 、plugins 、settings
检查是否有全局 Bash(*)、Edit(//**)、Write(//**)
检查代理/MITM 方向,没有发现本地证书/MITM 证据
检查相关 GitHub issue ,发现不是孤例
比较像的公开 issue:
Phantom user messages: https://github.com/anthropics/claude-code/issues/58671
Opus 4.8 生成不存在的 user input ,版本 2.1.177: https://github.com/anthropics/claude-code/issues/68159
Agent 编造 prompt-injection incident: https://github.com/anthropics/claude-code/issues/63871
harness 控制文本和 tool-result 共用未标记通道: https://github.com/anthropics/claude-code/issues/64539
命令执行期间消息和输出边界不清: https://github.com/anthropics/claude-code/issues/49625
https://github.com/anthropics/claude-code/issues/66711 这个更类似
我现在的临时处理:
降回 Claude Code 2.1.174
关闭 acceptEdits
移除全局 Edit(//**) / Write(//**)
去掉某个项目 local settings 里的 "*"
不 resume 出问题的旧会话
长会话里一旦 Claude 说“你刚才说过”,直接查 JSONL ,不跟模型争记忆
个人感觉,这个问题危险点不在于“模型胡说”本身,而在于 Claude Code 这种 agent 工具会把模型判断连接到真实文件操作。如果 user/tool/system/harness 的边界不够硬,模型把 tool_result 或自己的推理当成用户指令,再叠加自动写权限,就可能真的改文件。
想问下大家:
有人最近在 Claude Code 2.1.177 / Opus 4.8 遇到过类似 phantom user message 吗?
你们会不会长期打开 acceptEdits ?
有没有比较稳的 Claude Code 权限配置实践?
除了查 JSONL ,还有没有更好的方式确认“这句话到底是不是我发的”?
上述内容是我跟 codex 一起排查后让他总结的,搞的有点吓人哦,跟 claude 对话过程中好几次出现你刚才说 xx 我就 xx ,但是我完全没说,就像被对话注入的感觉。
先说结论:目前没有证据表明本机被黑,也没有证据表明是代理/MITM/某个 App 在篡改内容。更像是 Claude Code 的 harness / transcript / tool result / user turn 边界在长会话里混乱,加上模型归因漂移。
环境大概是:
macOS
Claude Code 2.1.177
Opus 4.8
acceptEdits 当时是开启的
会话较长,包含大量工具调用、interrupt 、截图、resume 、hooks 、插件上下文
最典型的现象有两个。
第一个:Claude 说“你上一条原话是:8.0.10+8010 我已经发布了,刚刚构建的,那他 symbol 不就被覆盖了?”。
但我查了本地 JSONL transcript ,这句话根本不是我的用户消息。8.0.10+8010 最早来自一次 shell 工具输出里的 pubspec version 当前值。Claude 后面把这个工具输出和它自己的推理拼成了一句“我的原话”。
第二个:我让它“返回这个会话中我发过的所有消息”,它内部 thinking 里提到了“第 15 条 可以”“第 16 条 不用读了,工作纪律下,你来写,注意脱敏”。但查原始 JSONL 后发现,这两句也没有作为真实 user message 出现。所谓第 15/16 条,如果按 JSONL 的 type=user 粗暴编号,其实是 tool_result ,而不是人类输入。
更糟糕的是,因为当时开着 acceptEdits ,Claude 后面真的擅自写了一个 memory 文件。文件后来我已经删了。
我做过的排查:
检查原始 JSONL transcript ,区分了真正用户消息、tool_result 、assistant thinking 、queue-operation
检查本地 hooks 、plugins 、settings
检查是否有全局 Bash(*)、Edit(//**)、Write(//**)
检查代理/MITM 方向,没有发现本地证书/MITM 证据
检查相关 GitHub issue ,发现不是孤例
比较像的公开 issue:
Phantom user messages: https://github.com/anthropics/claude-code/issues/58671
Opus 4.8 生成不存在的 user input ,版本 2.1.177: https://github.com/anthropics/claude-code/issues/68159
Agent 编造 prompt-injection incident: https://github.com/anthropics/claude-code/issues/63871
harness 控制文本和 tool-result 共用未标记通道: https://github.com/anthropics/claude-code/issues/64539
命令执行期间消息和输出边界不清: https://github.com/anthropics/claude-code/issues/49625
https://github.com/anthropics/claude-code/issues/66711 这个更类似
我现在的临时处理:
降回 Claude Code 2.1.174
关闭 acceptEdits
移除全局 Edit(//**) / Write(//**)
去掉某个项目 local settings 里的 "*"
不 resume 出问题的旧会话
长会话里一旦 Claude 说“你刚才说过”,直接查 JSONL ,不跟模型争记忆
个人感觉,这个问题危险点不在于“模型胡说”本身,而在于 Claude Code 这种 agent 工具会把模型判断连接到真实文件操作。如果 user/tool/system/harness 的边界不够硬,模型把 tool_result 或自己的推理当成用户指令,再叠加自动写权限,就可能真的改文件。
想问下大家:
有人最近在 Claude Code 2.1.177 / Opus 4.8 遇到过类似 phantom user message 吗?
你们会不会长期打开 acceptEdits ?
有没有比较稳的 Claude Code 权限配置实践?
除了查 JSONL ,还有没有更好的方式确认“这句话到底是不是我发的”?
上述内容是我跟 codex 一起排查后让他总结的,搞的有点吓人哦,跟 claude 对话过程中好几次出现你刚才说 xx 我就 xx ,但是我完全没说,就像被对话注入的感觉。