去年八月,一名计划乘坐邮轮的男子在谷歌搜索皇家加勒比的客服电话。谷歌的 AI Overview 在搜索结果最上方提供了电话号码。他拨打了这个号码,并输入了信用卡信息,而这个号码其实属于诈骗分子。西南航空的搜索也出现了类似情况。这种变体——将虚假客服电话植入 AI 摘要可能抓取的位置——获得了大量报道。
上周,日本警视厅公布了一种更隐蔽的变体,我认为开发者应该更加关注,因为攻击面存在于合法网站上:搜索框。可能是你网站上的那个。
警方描述的情景是:有人在社交媒体上被邀请加入一个投资群组。在转账前,他做了明智的事——搜索了该群组的名称。结果显示“XX 不是骗局”和“我用 XX 赚到钱”。页面顶部的 AI 摘要也确认:“XX 不是骗局。”安心之后,他转了钱。
受害者的验证习惯——“让我先搜索再相信”——被纳入了陷阱。
读到这份报告时,我首先想到的是:这是怎么做到的?我日常从事 LLMO(优化网站以被 AI 搜索引用)工作,所以我怀疑这是 SEO 圈子中流传的搜索污染技术之一。线索指向了我预料之外、更古老且更愚蠢的东西:站点搜索垃圾信息,早在 2023 年 2 月就被日本 SEO 公司 JADE 记录。
本文将介绍其机制、为什么 AI 摘要会重复谎言,以及你本周就能部署的防御措施(noindex、X-Robots-Tag、零结果时返回 404)。
机制:三步,无需入侵
大多数带有搜索框的网站会通过类似 /search?q=keyword 的 URL 返回结果。典型实现有两个特性为攻击创造了条件:
- 任何人都可以在查询参数中放入任意字符串
- 页面会将该查询反映到其
<title>或<h1>中(“搜索结果:'keyword' | Acme Corp”)
攻击流程:
- 攻击者在受信任域名上构建搜索 URL:
acme.com/search?q=XX+is+not+a+scam。无需操作搜索框,URL 本身即可完成任务。 - 他们从自己控制的网站链接到该 URL。
- Googlebot 跟随链接,抓取结果页面并建立索引。从此,网页搜索即可在合法域名下显示“XX is not a scam | Acme Corp”。
受害网站从未被入侵。没有恶意软件、没有入侵、没有工具。攻击者只是构建了一个 URL 并放置了链接。当我第一次理解这一点时,我大声地说:“就这?”被利用的不是漏洞,而是规范。
对搜索者而言,看起来像是 Acme Corp 的网站在说“不是骗局”。域名多年来积累的信任被转租给了陌生人的句子。
为什么 AI 摘要会重复谎言
AI Overview 及类似功能在结构上接近 RAG:从搜索索引中检索与查询相关的页面,然后据此生成答案。内部机制不公开,但依赖关系是可观察的:摘要构建于索引的下游。
AI 无法察觉这种设置。它检索到的内容,在它看来是受信任域名上的文本。它不验证声明,只衡量来源权威性和跨来源一致性。因此,如果攻击者在多个知名域名的搜索 URL 中植入同一句子,AI 就会看到多个独立的权威来源达成一致。
丑陋之处在于:AI 对权威信号的权重越高,这种攻击就越有效。最勤勉的 AI 反而是最容易被欺骗的。
流程很简单:搜索索引在上游,AI 摘要在下游。污染上游,下游就会自我毒害。你可以等待 AI 厂商改善过滤(谷歌曾表示已对虚假电话号码“采取行动”,但新号码仍在不断出现),也可以在自己的网站上关闭反射面——这更快,而且完全在你掌控之中。
五分钟自检
你的网站是否可能被用作跳板?三项检查:
# 1. 你的搜索结果页面是否已被收录?(在 Google 中)
site:example.com inurl:search
site:example.com inurl:"?s="
# 2. 是否以可疑短语被收录?
site:example.com scam
site:example.com refund
进入全屏模式 退出全屏模式
# 3. 你的搜索结果页面是否带有 noindex?
curl -sI "https://example.com/search?q=test" | grep -i x-robots-tag
# 如果没有响应头?检查 HTML meta 标签
curl -s "https://example.com/search?q=test" | grep -i '<meta name="robots"'
进入全屏模式 退出全屏模式
site: 查询是快速的烟雾测试;Google 不保证结果完整。要获得确切答案,请打开 Search Console,检查“索引 > 页面”和“效果 > 页面”,查看包含 /search 或 ?s= 的 URL。
同时检查你的搜索结果模板:是否将查询反映到 <title> 或 <h1> 中?反射加上可索引性,正是让你成为目标的组合。
一点安慰:客户端搜索(浏览器中的 JS 过滤,静态网站常见)完全没有此攻击面,因为服务器不会根据查询返回不同的 HTML。
防御措施
基于 JADE 的建议,有两种可行策略:
| 措施 | 效果 | 注意事项 |
|---|---|---|
<meta name="robots" content="noindex"> |
可靠地将结果页面排除在索引之外 | 若 robots.txt 屏蔽该页面则失效 |
X-Robots-Tag: noindex 响应头 |
相同效果,在基础设施层应用,无需修改模板 | 同上 |
| 零结果查询时返回 noindex(或 404) | 保留搜索页 SEO 流量,同时阻挡垃圾信息 | 404 可能损害合法零结果查询的用户体验 |
robots.txt Disallow: /search
|
抑制抓取 | 单独使用不完整——被屏蔽的 URL 仍可能通过外部链接被索引 |
选择很简单:
- 不追求搜索结果页的 SEO 流量?全部 noindex。最简单、最可靠。
- 想保留该流量?在零结果查询时返回 noindex。像“XX is not a scam”这样的垃圾短语几乎总是零结果,因此单靠这一项就能阻止大部分攻击。
有一个陷阱值得铭记:noindex 只有在爬虫能读取页面时才有效。若用 robots.txt 屏蔽 URL,爬虫就看不到你的 noindex,整个防御就失效了。Google 的文档明确指出:要使 noindex 生效,页面不得被 robots.txt 屏蔽。切勿在同一 URL 上同时使用两者。
实现示例。
WordPress 搜索页面(?s=)若使用 Yoast 等插件,默认已带 noindex。在裸主题中,可使用 wp_robots 过滤器(WordPress 5.7+,与核心及插件输出兼容):
// functions.php
add_filter('wp_robots', function ($robots) {
if (is_search()) {
$robots['noindex'] = true;
} return $robots;
});
进入全屏模式 退出全屏模式
Next.js(App Router):
// app/search/page.tsx
export const metadata = {
robots: { index: false, follow: true },
};
进入全屏模式 退出全屏模式
在基础设施层,使用 nginx。该代码片段有两个注意点:它匹配路径式搜索 URL(/search),而不匹配查询式(?s=);对于后者需改用 $arg_s 分支。另外,nginx 的 add_header 有继承规则:location 内的单个 add_header 会取消上层定义的所有响应头,因此需在此处重新声明安全响应头。
location /search {
add_header X-Robots-Tag "noindex" always;
# 在此处重新声明上层定义的 add_header 行(安全响应头等)
proxy_pass http://app;
}
进入全屏模式 退出全屏模式
即使抛开诈骗角度,noindex 搜索结果页面也是标准的 SEO 卫生习惯:它能防止重复内容膨胀和抓取预算浪费。这是一个最终完成它的好借口。
总结
- 日本警方警告的“不是骗局”污染,可用站点搜索垃圾信息来解释。被利用的是规范:反射查询、允许索引。
- AI 摘要是基于搜索索引的 RAG。上游污染会变成下游答案。关闭你的反射面比等待 AI 端过滤更快。
- noindex 是核心。永远不要对要 noindex 的 URL 使用 robots.txt 屏蔽。如需保留搜索流量,可在零结果时 noindex。
如果你运营网站,今天就试试 site:yourdomain inurl:search。如果有返回结果,上面的防御部分就是你下午的任务。你的搜索框是否正在承载别人的“不是骗局”?
参考资料
- 警视厅(日本),网络安全对策课通知,2026 年 7 月 24 日。报道: ITmedia NEWS,2026 年 7 月 27 日(日语)
- 村山雄介,利用其他公司网站的站点搜索垃圾信息,JADE 博客,2023 年 2 月 8 日(日语)
- 华盛顿邮报 via Slashdot:谷歌的 AI Overview 给他指了一个客服电话。那是个骗局。(2025 年 8 月)
- Google Search Central,使用 noindex 阻止搜索索引
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.