术语表

什么是点击劫持?把透明页面叠在另一个页面上、诱导你点击其中按钮的攻击

点击劫持是把真实页面变透明后叠在其他网站上、诱导用户点击看不见的按钮的攻击。图解原理,并讲解用 CSP frame-ancestors 与 X-Frame-Options 禁止被他站嵌入的防御。

发布于 2026-06-10 更新于 2026-10-06 3 分钟阅读
本页目录

点击劫持会诱导你点击叠在所见页面下方的隐藏页面上的按钮。本文讲解其原理与可靠的防御方法(不公开攻击步骤)。

什么会被盯上

「一键即可完成、而且有价值的操作」是攻击目标。

容易被盯上的操作为什么会被盯上
转账、购买的确认一键即可让金钱发生流动
修改设置(可见范围、授权许可)之后会导致账号被接管或信息被获取
OAuth/权限的「允许」按钮被擅自批准账号关联授权
社交媒体的关注、点赞、发帖被滥用于擅自传播、刷赞

为什么会成立(原理)

浏览器可以用 iframe 加载另一个站点并叠加显示。攻击者把这个 iframe 设为透明(不透明度为 0),用户看到的只有放在下方的假 UI。用户按下「假按钮」时,从坐标上看,正叠加在其上方的真实按钮就被按下了。

攻击者的页面「您中奖了!请按下方按钮」
= 叠加着透明的 iframe(真实的银行/设置页面)
↓ 用户按下「看得见的假按钮」
实际被按下的是正上方真实的「执行」按钮
↓ 在本人已登录的状态下
转账、修改设置、授权作为「本人的操作」完成
在攻击者的页面上把真实站点透明叠加,看得见的只有假 UI。点击落在了透明的真实页面上。

它与 CSRF 相似,但 CSRF 是「在背后发送请求」,而点击劫持是让本人去操作真实的画面,因此仅靠一次性令牌等 CSRF 对策无法防御。

真实案例:浏览器插件的权限对话框(2008 年)

2008 年 10 月,Adobe 发布了一则关于影响多种浏览器的点击劫持问题的安全通告(APSA08-08)。据媒体报道,通过把 Flash Player 的设置对话框透明叠加,网站可以让用户在不知情的情况下授予它访问摄像头和麦克风的权限。Adobe 发布了修复版的 Flash Player,并作为临时规避措施,建议用户在设置管理器中选择「始终拒绝」。

教训是:被盯上的不只是转账按钮。凡是点一下就交出权限的画面(「允许」「同意」「关联」)都在范围之内。MITRE 把这一弱点归类为 CWE-1021(对渲染的 UI 图层或框架限制不当)。

防御:不让其他站点嵌入你的站点

1

设置 CSP frame-ancestors(最优先)

在响应头中加入 Content-Security-Policy: frame-ancestors 'self'(仅允许自己的站点框架化)。如果不需要让第三方嵌入,用 'none' 最安全。只有在确有需要允许的对象时才逐一列出域名。

2

同时使用 X-Frame-Options(向后兼容)

为了照顾老旧环境,也加上 X-Frame-Options: DENY(或 SAMEORIGIN)。这样新旧浏览器都能覆盖。

3

对重要操作加入确认步骤

转账、授予权限等致命操作,要插入二次认证、确认对话框、操作前的意图确认。这样透明叠加就更难突破。

4

把会话 Cookie 设为 SameSite

用 SameSite=Lax/Strict 抑制来自其他站点的自动发送。它对点击劫持本身并非万能,但能削弱相关的各类「源自他站的操作」。

X-Frame-Options 与 CSP frame-ancestors 的区别

两个响应头都能阻止其他站点嵌入你的站点,但细节不同。

X-Frame-OptionsCSP frame-ancestors
取值DENY(全部禁止)/ SAMEORIGIN(仅同源)'none' / 'self' / 允许的域名列表
允许多个嵌入方不可以(ALLOW-FROM 在现代浏览器中不起作用)可以
用 meta 标签设置不起作用不起作用
两者同时存在时被支持 frame-ancestors 的浏览器忽略优先采用
定位面向旧浏览器的后备当今的主要防御

同时发送两者时,要让含义一致:frame-ancestors 'none' 搭配 DENY,frame-ancestors 'self' 搭配 SAMEORIGIN。

常见的配置失误

  • 以为 CSP 的 default-src 已经覆盖了。frame-ancestors 不会回退到 default-src。即使写了 default-src 'none',只要没写 frame-ancestors,嵌入仍然是允许的
  • 写在 meta 标签里:<meta http-equiv> 在这里不起作用,要作为响应头发送
  • 停留在 Content-Security-Policy-Report-Only:它只报告违规,不会阻止嵌入。确认运行正常后,切换为强制生效的响应头
  • 只在部分页面设置:人们检查了首页,却漏掉了登录页、设置页或错误页。还要确认 CDN 或代理没有把响应头去掉

如何检查自己的站点

1

用响应头检测工具检查

在安全响应头检查中输入你站点的 URL,看是否返回了 X-Frame-Options 和 CSP 的 frame-ancestors。不只是首页,还要检查登录后的设置页,以及转账或授予权限的页面。

2

在浏览器的开发者工具中检查

打开「网络」标签页重新加载页面,查看 HTML 响应的响应头。同时确认响应头没有被发送两次,或者取值互相矛盾。

3

在一处统一设置

在一个地方(nginx、Caddy 等 Web 服务器、反向代理或框架)对所有响应统一添加,可以同时防止遗漏和重复。如果要新写 CSP,可以用 CSP 生成器组装包含 frame-ancestors 的策略。

本站的观点:一行响应头最有效,先检查自己的站点

点击劫持的对策不是复杂的代码,而是用一到两行响应头阻止嵌入。在框架或反向代理(Caddy/nginx)上对所有页面统一加上,避免遗漏。最常见的失误是以为已经设置好了,实际上响应头却漏掉了,所以设置之后,请按上面的步骤确认它确实被返回了。

出处(一手资料)

  • OWASP,“Clickjacking Defense Cheat Sheet” — cheatsheetseries.owasp.org(frame-ancestors、X-Frame-Options、SameSite;ALLOW-FROM 已不起作用;meta 标签不起作用;frame busting 的局限)
  • MDN,“CSP: frame-ancestors” — developer.mozilla.org(允许的取值、不回退到 default-src、meta 中不支持)
  • RFC 7034,“HTTP Header Field X-Frame-Options” — rfc-editor.org
  • IPA,《安全网站的制作方法》1.9 点击劫持(日文) — ipa.go.jp
  • Adobe,“Security Advisory for Flash Player (APSA08-08)”(2008 年 10 月 7 日) — adobe.com
  • Computerworld,“Clickjackers could hijack webcams, microphones, Adobe warns”(2008 年 10 月) — computerworld.com(被盯上的是摄像头和麦克风的权限对话框)
  • MITRE,“CWE-1021: Improper Restriction of Rendered UI Layers or Frames” — cwe.mitre.org

接下来阅读

分类编号

CWE 对导致漏洞的弱点类型进行分类,MITRE ATT&CK 对攻击者的技术进行分类。两者均由 MITRE 维护,广泛用于标注漏洞信息和检测规则。

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

FAQ

Q点击劫持会让人遭受什么?
A

用户「自以为」按下的点击,实际落在了叠加于背后那个真实页面的按钮上。一键转账、修改设置、授予权限、在社交媒体上关注/点赞、同意按钮等「一键即可完成的重要操作」都会被滥用。它的特点不是窃取密码,而是让已登录的用户本人去执行操作。

Q最有效的防御是什么?
A

就是「不让自己的站点被嵌入到他站的框架(iframe)里」。在响应头中把 CSP 的 frame-ancestors 设为 'self'(或仅允许指定域名),并为了向后兼容同时使用 X-Frame-Options: DENY。这样攻击者就无法进行叠加。

Q只靠 JavaScript 的 frame busting(跳出框架)够吗?
A

不够。老式的「如果发现自己在 iframe 内就跳出去」的 JS 有很多绕过手法,且在 JS 被禁用时无法防护。可靠的防御是用服务器端的响应头(frame-ancestors / X-Frame-Options),让浏览器直接拒绝被嵌入。

QX-Frame-Options 和 CSP frame-ancestors,该用哪个?
A

两者都发送,并让含义一致,这是标准做法。frame-ancestors 可以列出多个允许嵌入的站点,两者同时存在时,支持它的浏览器会采用 frame-ancestors。X-Frame-Options 是面向旧浏览器的后备。'none' 搭配 DENY,'self' 搭配 SAMEORIGIN。

Q可以用 HTML 的 meta 标签来设置吗?
A

不可以。frame-ancestors 写在 meta 元素中不起作用,X-Frame-Options 写在 meta 元素中也会被忽略。两者都必须作为 HTTP 响应头发送,在 Web 服务器、反向代理或框架中设置。

Q需要允许自己的其他站点或合作方嵌入页面时怎么办?
A

在 frame-ancestors 中列出允许的对象(例如 frame-ancestors 'self' https://partner.example)。X-Frame-Options 的 ALLOW-FROM 在现代浏览器中不起作用,不要依赖它来做允许清单。只对确实需要嵌入的页面和域名放行。