Vue嵌套路由页面如何防御Strokejacking攻击?

❤欧辰 阅读 42

我在开发一个Vue项目时,用户页面需要嵌入第三方的表单页面。最近测试时发现,攻击者可能通过iframe嵌套我们的表单页,用透明层覆盖实现Strokejacking。尝试在后端设置X-Frame-Options: DENY,但发现嵌入的页面仍然能被加载,这到底是哪里出错了?

尝试过以下方法:
1. 在Nginx配置加了add_header X-Frame-Options SAMEORIGIN;
2. Vue组件里动态设置allow attribute:

mounted() {
  this.$el.setAttribute('allow', 'prevent-frame-navigation');
}

但iframe仍然能显示页面,该怎么彻底阻止跨域嵌套呢?

我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
令狐雯雯
前端这块你遇到的问题其实挺典型的,X-Frame-Options没生效,大概率是因为响应头根本没正确返回。

先说重点:你在 Nginx 加了 add_header,但这个指令在 Nginx 的子请求或者某些条件下是不会生效的,尤其是当有 location 匹配冲突、或者被 proxy_pass 覆盖的时候。你要确保这个 header 是从你真正返回 HTML 的那个服务端出口发出来的,比如后端接口或静态资源服务。

你可以打开浏览器开发者工具,Network 里找你的页面 HTML 响应,看 Response Headers 有没有 X-Frame-Options。如果没有,那就说明配置白加了。

另外,X-Frame-Options 只支持三个值:DENY、SAMEORIGIN、ALLOW-FROM(但 ALLOW-FROM 兼容性极差,基本不能用)。所以如果你是想完全禁止嵌套,必须确保所有环境都返回 X-Frame-Options: DENY,并且这个 header 是直接由服务端返回 HTML 时带上的。

Vue 组件里 setAttribute('allow', 'prevent-frame-navigation') 这种写法是无效的,allow 属性是用在 iframe 标签上的,不是给根元素随便设的,这完全不起作用。

正确的防御方式就两条:

1. 确保服务端(Nginx 或后端)对页面的 HTML 响应返回 X-Frame-Options: DENY,并且在所有环境下都能看到这个 header。
2. 同时加上 Content-Security-Policy: frame-ancestors 'none';,这是现代浏览器推荐的方式,比 X-Frame-Options 更强更灵活。如果是只允许同域,就设为 frame-ancestors 'self';

比如 Nginx 配置:
add_header X-Frame-Options DENY;
add_header Content-Security-Policy "frame-ancestors 'none';";


最后提醒一点:如果第三方表单页是你自己控制的域名,那也要在那个服务上同样设置;如果是别人家的页面,那你根本防不住他们嵌你,只能保证自己不被别人嵌。Strokejacking 主要靠防止被嵌套来解决,别指望前端 JS 能搞定这事。

检查下你现在线上页面的响应头,八成是根本没返回这些安全头,光代码里折腾没用。
点赞 1
2026-02-12 08:27
IT人东昇
你这个问题是典型的嵌套防护没做到位。X-Frame-Options虽然能起到一定作用,但有时候单靠它确实不够,尤其是Vue这种前端框架和后端配合的时候容易出问题。

首先,Nginx的add_header X-Frame-Options SAMEORIGIN;是没错的,但它只对同源生效。如果你的页面被跨域嵌套了,还需要在前端加一道防线。直接在Vue组件里写个简单的判断:

if (window.top !== window.self) {
window.top.location = window.self.location;
}


这段代码的作用是:如果当前页面被iframe嵌套了(也就是window.top不是自己),就强制跳转到顶层窗口。这种方法简单粗暴,兼容性也很好。

另外,你说的那个allow属性其实是个新玩意儿,主要是针对某些特定的安全策略,但对付 Strokejacking 还是上面那段代码更靠谱。

最后提醒一下,后端的X-Frame-Options还是要保留,前后端结合才能更稳妥。如果项目有CSP(内容安全策略),也可以加上frame-ancestors 'self';,双重保险总是好的。
点赞 10
2026-01-29 10:07