0x00 背景

前端的 js 投毒/恶意 html/xss 的问题在互联网公司基础安全建设进入中后期时,矛盾会开始逐渐暴凸显,结合钓鱼、白名单下 xss、终端高权限 API 等可以展现出不小的威力,检测/加固较难实现通用化的覆盖能力。非 SDL/WSL 背景,从基础知识谈起,分享一个实际遇到的经典 因CORS 配置不当 + CSRF导致的 1 click rce的例子。

0x01 基础知识

温习一下基础的常见知识。

同源策略:A 站点请求 B 站点资源,受同源策略(Same-Origin Policy)保护,存在限制(操作 DOM、读取存储 cookie/localstorage/获取网络请求响应)
跨域请求:A 站点请求 跨域的B 站点资源,请求能发出去,但响应内容 浏览器会限制加载(除非服务器允许)。
跨域解决经典方案(CORS):配置方式服务端设置ACAO响应头:

Access-Control-Allow-Origin: https://www.example.com  
Access-Control-Allow-Credentials: true

重点1:跨域时会携带 cookie 吗?默认不携带。满足4个条件时携带:
1)js 请求显示支持credentials :fetch(url, { credentials: 'include' })
2)ACAO开启(非泛域名) + ACAC 配置为 true:本质上是允许哪些网站携带身份请求你的 API。

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://www.example.com  // 不能是 *

3)cookie 配置SameSite为 None + Secure(仅允许 https 传输)
4)chrome浏览器配置:默认 允许第三方 cookie。(chrome://settings/cookies)

重点2:没配置 ACAO 头,A还可以发跨域请求给 B么?
可以,走 fetch no-cors模式,无法获取响应内容。用于打点日志上报 / 一次请求可以直接rce 的场景。

0x02 业务场景

业务场景下,B 站点通常会有一堆A站点携带票据来访问,因此ACAO通常的配置方式如下,允许合法 Origin 携带票据请求

// Node.js / Express
const whiteList = [
  'https://www.example.com',
  'https://admin.example.com'
];
app.use((req, res, next) => {
  const origin = req.headers.origin;
  if (whiteList.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);  // 动态回显
    res.setHeader('Access-Control-Allow-Credentials', 'true');
    res.setHeader('Vary', 'Origin');  // 防止 CDN 缓存串
  }
  next();
});

Origin 的 whitelist 配置不当/缺失:没有白名单,信任任意 Origin: 都可以请求,返回对应的 Access-Control-Allow-Origin:

2、业务存在敏感功能(较为普遍):获取身份信息、执行命令等(往往只有 SSO 认证)

3、业务开发速度较快(较为普遍):整体接口无CSRF 检查(referer check、csrf-token)

0x03 攻击面分析

攻击面1:2+3缺失:结合一个业务同域名下的恶意的 html,就可以做到CSRF 攻击。
攻击面2: 2+3缺失 + 1缺失:任意域名下即可发起 跨域请求 +CSRF 攻击。

1、业务快速上线时,2和3大概率是没有的,接了sso 认证就很不错了。
2、业务需要对外暴露时,支持动态白名单也是有成本的,干脆省略白名单(尤其是内网应用),直接上线。
3、csrf 的安全 sdk 的接入:refer 本质上也是白名单检查,业务懒得配置;随机 token 如果无框架业务自己实现成本过高。

0x04 实际案例分享

实际在业务快速上线时,遇到了一个真实业务:存在命令执行的接口、对外暴露了业务自定义生成 html 的能力。上述问题1、2、3都存在,因此上述提到的2个攻击面,实际的利用情况如下,较为隐蔽难以检测。

  • 针对上述提到的攻击面1,伪造一个钓鱼链接,windows.locaton.href 跳转到同源下的恶意 html发起 CSRF 攻击。
  • 针对上述提到的攻击面2,在任意站点投放恶意的 js 发起攻击
    1 click rce:

ROI 较高的几个修复方案:
1、核心接口单独配置 Origin 白名单,不在白名单则返回403.
2、站点整体 CORS 加固,配置白名单
3、CSRF修复:referer 白名单检查,禁止空 referer。

0x05 感受与思考

为什么公司业务常常只配了认证,不配置 CSRF防护?研发定制成本过高(框架不支持)、通用安全 sdk接入成本(referer 配置)、随机 token 的实现成本(中间层 filter 开发与检查)、大部分接口危害优先不值得被攻击。

自动化能力:黑白盒层面针对 CORS 配置不当、无 CSRF 的检查通常最多作为中危漏洞去修复,修复进度会比较慢。(实际能力待补充)

AI 时代,有问题则代表有机会,相信会有更好的解决方案。