防御点击劫持的唯一有效方式是服务端设置content-security-policy: frame-ancestors指令,禁止页面被嵌入;x-frame-options已逐步被取代,前端js检测或屏蔽object点击等手段均无效且危险。

object 标签本身不是点击劫持的攻击面,而是被嵌入的目标容器之一。你无法靠“防住 object 标签的点击”来防御点击劫持——这就像给门把手贴胶带,却忘了锁门。
真正的防护点只有一个:阻止你的整个页面被嵌入恶意 iframe。而 object、iframe、embed 这些标签,只是攻击者用来加载你页面的载体。它们是否可点击、是否响应事件,完全不改变攻击成立的前提。
怎么验证 object 是否参与了点击劫持风险
- 攻击者不会用
object src="@#@#@#@#@#@#@#@#@#@0">去套你的敏感页(object不支持跨源导航或表单提交,兼容性也差); - 但如果你的页面本身被嵌进别人的
iframe,而你页面里又用了object加载富媒体(如 PDF、Flash 替代方案),那它可能成为攻击链中“可见但不可控”的一部分; - 更常见的是:你用
object加载第三方内容(比如某个报表组件),结果那个第三方内容自身存在 XSS 或可被劫持,反向污染你的上下文。
所以重点不是“怎么禁掉 object 的 click”,而是:
- 确认你的页面不被任意站点嵌入(靠服务端 CSP);
- 若必须允许嵌入(如 SaaS 嵌入式仪表盘),则对
object加载的第三方资源做严格域名白名单 + sandbox 属性; - 不要用
object加载用户可控的 URL(比如object?src=xxx拼接),否则直接引入 XSS。
object 标签自身的点击行为能被 JS 屏蔽吗
可以,但毫无安全意义:
-
event.preventDefault()对object的 click 无效(它不触发标准 DOM click 事件,尤其加载 PDF/Flash 时); -
pointer-events: none能让鼠标穿透,但攻击者只要把object放在底层、用上层 div 覆盖按钮,照样劫持; - 给
object外层加遮罩 div,只影响视觉,不阻止 iframe 已加载完成后的坐标映射。
也就是说:所有针对 object 单独做的前端拦截,既挡不住嵌入,也拦不了事件穿透,纯属干扰项。
正确做法:把防护锚点钉死在服务端响应头
你真正该检查的,是访问含 object 标签的 HTML 页面时,HTTP 响应头里有没有:
Content-Security-Policy: frame-ancestors 'none';
或者至少:
Content-Security-Policy: frame-ancestors 'self' @#@#@#@#@#@#@#@#@#@1;
- 如果没这个 header,哪怕你给每个
object都加了onclick="return false",攻击者仍可用iframe src="your-page.html"完整加载它,并叠一层透明按钮; - 如果 header 存在且语法正确(注意单引号、分号、空格分隔),浏览器根本不会加载你的页面进任何 iframe ——
object根本没机会被渲染。
最常漏掉的细节:
- Nginx 配置里漏了
always参数,导致 304 响应不带 header; - Django 用户只启用了
XFrameOptionsMiddleware,却没关掉旧的X-Frame-Options,导致和 CSP 冲突; - 本地开发时 Vite 自动注入了 CSP,上线后后端没配,一测就崩。
别碰 object 的 click 事件监听器。去查 curl -I 返回里有没有那一行 Content-Security-Policy。没有,就等于没防。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











