网页同源泄密防范思路

QBin支持用户创建HTML代码,并且支持通过/r/xxx 路径显示渲染后的界面。
那么就可能存在同源恶意攻击问题,那么如何防止这个问题,并且不影响正常用户使用呢?
这就是我们接下来需要讨论的问题。


在浏览器中进行网络请求都会强制携带一些headers信息,我们要关心的就是RefererOrigin
通过 referer和origin 我们可以知道这个请求来自哪里,那么就可以根据这些信息针对特定路径进行检测。

刚开始我的解决方法是增加一个中间件,在必要的接口中增加检测,关键代码如下

const referer = ctx.request.headers.get("referer");
if (referer && referer.includes("/r/")) {
  return new Response(ctx, 403, "不允许从分享链接页面请求token");
}

这个代码看似没有问题,其实还存在缺陷,前端可以修改referrer-policy,就会出现匹配不到的问题,下面是绕过检测成功的攻击案例

虽然前端修改了referrer-policy,但还是会在referrer携带 host,那么就可以改进检测规则

// 获取基本请求信息
const referer = ctx.request.headers.get("referer");
const origin = ctx.request.headers.get("origin");

if (!referer || referer.includes("/r/")) {
  return new Response(ctx, 403, "不允许从同源链接页面请求token");
}
if (referer === origin) {
  return new Response(ctx, 403, "检测到可疑的Referer策略");
}
const refererUrl = new URL(referer);
if (refererUrl.pathname === "/" || refererUrl.pathname === "") {
  return new Response(ctx, 403, "不允许使用仅包含域名的Referer");
}

除了上面的这些防范还不够,因为html不仅可以通过fetch请求,还可以通过表单提交等方式绕过,那么我们就需要为前端增加headers响应防范

{
    "X-Content-Type-Options": "nosniff",    // 禁止嗅探MIME类型
    "X-XSS-Protection": "1; mode=block",    // 启用XSS过滤器
    "X-Frame-Options": "DENY",              // 禁止页面在frame中展示
    // "Content-Security-Policy": "default-src 'self'",  // 同源加载
    "Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload",  // HSTS强制使用HTTPS
    "Referrer-Policy": "strict-origin-when-cross-origin",      // 引用策略
},

更严格的"Content-Security-Policy": "default-src 'self'"策略是只允许同源域名请求,其他外链都会拒绝,虽然效果很好,但是实际应用中并不方便。

最后是防范成功的截图


伪攻击代码界面 边缘情况绕过测试
伪攻击代码源码 QBin


如果有其他思路,欢迎在评论区讨论

代码仅供学习参考,请勿用于其他用途

6 Likes

mark一下!!

2 Likes

收藏了,晚上看

2 Likes

:tieba_087: 感谢,看蒙了

2 Likes

代理跳转还是逃不过吧

1 Like

后端配置cookie只能同源请求,外链和本地js获取不到cookie,请问代理跳转怎么绕过检测?

此话题已在最后回复的 30 天后被自动关闭。不再允许新回复。