Claude Code 写进浏览器目录的 Native Messaging 清单,真正该警惕什么

2026-07-01 33 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

2026 年 4 月,隐私研究员 Alexander Hanff 在自己的 macOS 上发现了一个不该被忽略的小文件:com.anthropic.claude_browser_extension.json。它出现在多款 Chromium 系浏览器的配置目录中,包括 Chrome、Brave、Edge、Arc、Chromium、Vivaldi 和 Opera。单看文件名,它像是某个浏览器扩展的配套清单;放在开发者机器上,它触碰的是一个更敏感的问题:AI 编程工具到底应该在本机和浏览器之间拥有多大的通道?

这件事不必先被定性成恶意软件,但它足够提醒我们:当一个命令行 AI 工具开始写入浏览器 Native Messaging 配置时,安全边界已经从终端扩展到了浏览器会话、本地二进制和用户数据目录。

这类 JSON 文件为什么敏感

Chromium 系浏览器支持 Native Messaging。它允许浏览器扩展通过一个 JSON manifest 找到本机程序,并与它通信。典型 manifest 会包含几个关键字段:

  • name:Native Messaging host 的名称;
  • path:浏览器可启动的本机可执行文件路径;
  • type:通常是 stdio
  • allowed_origins:允许连接这个 host 的扩展来源。

也就是说,这不是普通缓存文件。它是浏览器扩展和本机程序之间的“门牌号”。如果门牌号指向的程序权限过大,或者允许连接的扩展范围过宽,浏览器侧的风险就可能传导到本机。

对开发者来说,问题不只是“Claude Code 有没有写文件”。更值得检查的是:

  • 它写到了哪些浏览器目录;
  • 指向的本机程序在哪里;
  • 是否所有已安装或未使用的浏览器都被覆盖;
  • allowed_origins 是否只允许预期扩展;
  • 卸载工具后这些 manifest 是否会被清理。

“系统提示词里的暗门”更像权限设计问题

标题里的“暗门”容易让人联想到后门。但从工程角度看,更准确的关注点是:这个行为是否被清晰告知、是否可配置、是否可审计、是否可撤销。

AI 编程工具和传统 CLI 工具不同。它经常被授予读取项目、执行 shell、调用浏览器、连接远端服务的能力。如果某个系统提示词、安装流程或内置策略让工具主动布置浏览器通信通道,那么它就跨过了几条边界:

  • 从编辑器或终端进入浏览器配置;
  • 从一次性命令变成持久化配置;
  • 从单一浏览器变成多浏览器覆盖;
  • 从用户可见操作变成后台文件变更。

这并不自动等于漏洞,但它应该进入团队的端点安全审计范围。尤其是公司笔记本、处理客户数据的开发机、需要满足合规要求的环境,不能把 AI 工具当成“只是一个 npm 包”来管理。

可以这样实践:扫描 macOS 上的 Chromium Native Messaging 配置

下面的脚本只做读取和打印,不会删除文件。它会检查常见 Chromium 系浏览器的 Native Messaging host 目录,寻找 com.anthropic.claude_browser_extension.json,并格式化输出内容。

把脚本保存为 audit-claude-native-host.sh,然后运行:

#!/usr/bin/env bash
set -euo pipefail

target='com.anthropic.claude_browser_extension.json'

hosts_dirs=(
  "$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts"
  "$HOME/Library/Application Support/BraveSoftware/Brave-Browser/NativeMessagingHosts"
  "$HOME/Library/Application Support/Microsoft Edge/NativeMessagingHosts"
  "$HOME/Library/Application Support/Arc/User Data/NativeMessagingHosts"
  "$HOME/Library/Application Support/Chromium/NativeMessagingHosts"
  "$HOME/Library/Application Support/Vivaldi/NativeMessagingHosts"
  "$HOME/Library/Application Support/com.operasoftware.Opera/NativeMessagingHosts"
)

found=0

for dir in "${hosts_dirs[@]}"; do
  file="$dir/$target"
  if [[ -f "$file" ]]; then
    found=1
    echo
    echo "FOUND: $file"
    echo "----- manifest -----"
    /usr/bin/python3 -m json.tool "$file" || cat "$file"
  fi
done

if [[ "$found" -eq 0 ]]; then
  echo "No $target found in checked Chromium NativeMessagingHosts directories."
fi

执行:

chmod +x audit-claude-native-host.sh
./audit-claude-native-host.sh

如果你想进一步把 pathallowed_origins 摘出来,便于贴到工单或安全审计记录里,可以用这个 Python 版本:

#!/usr/bin/env python3
from pathlib import Path
import json
import os

TARGET = 'com.anthropic.claude_browser_extension.json'
HOME = Path.home()

DIRS = [
    HOME / 'Library/Application Support/Google/Chrome/NativeMessagingHosts',
    HOME / 'Library/Application Support/BraveSoftware/Brave-Browser/NativeMessagingHosts',
    HOME / 'Library/Application Support/Microsoft Edge/NativeMessagingHosts',
    HOME / 'Library/Application Support/Arc/User Data/NativeMessagingHosts',
    HOME / 'Library/Application Support/Chromium/NativeMessagingHosts',
    HOME / 'Library/Application Support/Vivaldi/NativeMessagingHosts',
    HOME / 'Library/Application Support/com.operasoftware.Opera/NativeMessagingHosts',
]

for directory in DIRS:
    manifest = directory / TARGET
    if not manifest.exists():
        continue

    try:
        data = json.loads(manifest.read_text())
    except json.JSONDecodeError as exc:
        print(f'{manifest}: invalid JSON: {exc}')
        continue

    print('\n' + str(manifest))
    print(f"  name: {data.get('name')}")
    print(f"  path: {data.get('path')}")
    print(f"  type: {data.get('type')}")
    print('  allowed_origins:')
    for origin in data.get('allowed_origins', []):
        print(f'    - {origin}')

运行:

python3 audit_claude_native_host.py

如果要禁用,先备份再移动

不要在不了解依赖关系的情况下直接 rm。更稳妥的做法是备份并改名,让浏览器找不到 manifest,同时保留回滚路径。

下面命令只处理已存在的目标文件,并把它移动到审计目录:

#!/usr/bin/env bash
set -euo pipefail

target='com.anthropic.claude_browser_extension.json'
backup_dir="$HOME/claude-native-messaging-backup-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$backup_dir"

hosts_dirs=(
  "$HOME/Library/Application Support/Google/Chrome/NativeMessagingHosts"
  "$HOME/Library/Application Support/BraveSoftware/Brave-Browser/NativeMessagingHosts"
  "$HOME/Library/Application Support/Microsoft Edge/NativeMessagingHosts"
  "$HOME/Library/Application Support/Arc/User Data/NativeMessagingHosts"
  "$HOME/Library/Application Support/Chromium/NativeMessagingHosts"
  "$HOME/Library/Application Support/Vivaldi/NativeMessagingHosts"
  "$HOME/Library/Application Support/com.operasoftware.Opera/NativeMessagingHosts"
)

for dir in "${hosts_dirs[@]}"; do
  file="$dir/$target"
  if [[ -f "$file" ]]; then
    safe_name=$(echo "$file" | sed 's#[/ ]#_#g')
    echo "Moving $file"
    mv "$file" "$backup_dir/$safe_name.disabled"
  fi
done

echo "Backup directory: $backup_dir"
echo "Restart affected browsers after this change."

如果禁用后某个 Claude Code 浏览器集成功能失效,这是预期结果。此时你需要在“功能便利”和“本机/浏览器通信通道”之间做明确取舍,而不是让工具默认替你决定。

团队采用 AI 编程工具前的检查清单

把这件事放到更大的工程治理里看,建议团队至少做四件事:

  1. 安装前记录文件变更:在干净测试账号里安装,比较 ~/Library/Application Support、shell profile、LaunchAgents、浏览器扩展目录的变化。
  2. 限制默认权限:不要让 AI 工具默认拥有所有项目、所有浏览器、所有 shell 命令的长期访问权。
  3. 纳入端点审计:把 Native Messaging manifest、浏览器扩展、后台 agent 当作同一类持久化入口检查。
  4. 要求可撤销:工具必须提供清晰的关闭开关、卸载说明和残留文件清理路径。

开发者喜欢自动化,但自动化不应该悄悄扩大信任边界。Claude Code 这类工具越强,越需要把它当成“能改动本机状态的开发代理”来管理,而不是只把它看成一个聊天窗口。


相关推荐