Web安全草稿
# xss
根据拼接html的处理方分为两类 前端拼接 html ,有 DOM 型 XSS 攻击,内容可以是后端数据库/前端存储/URL
解决办法是需要对内容做处理,不直接采用不安全的API
后端拼接 html(服务端渲染),有存储型 XSS 和反射型 XSS 前者数据存到数据库,常见的就是论坛发帖
后者构造一个url,插入到 html,让用户点击并执行恶意代码,一般是服务端渲染时直接渲染 url 中的参数
解决办法是需要对内容做转义
需要注意的是,转义规则不是通用的,要根据具体场景具体处理
其他方案比如 csp 可以降低攻击后果,即使攻击了,数据不会泄露到外域
# csrf
https://tech.meituan.com/2018/10/11/fe-security-csrf.html
通过设置 Referrer Policy 进行同源监测 没有 referrer 的设置不可信(部分浏览器会无法使用
解决方案:
- 增加验证码(本质是服务端存了一个值,前端需要算到)
- CSRF Token 方案:向服务端请求并返回一个随机值,在请求发起时添加自定义请求头 如果值是纯随机生成的,则服务端需要使用 session 或 Redis 来记录;缺点:增加服务端压力且不适合分布式; 如果值使用对称加密算法生成(userId+时间戳+随机值),则服务端不需要额外存储,只需对称加密算法进行解密,将 userId 和时间戳来做有效性验证; 缺点:
- 如果加密算法暴露的话,就可以进行伪造
- token 校验有点侵入业务,无法使用单独的安全网关层进行
- 双重 cookie :利用 csrf 攻击无法读取 cookie 的特点,向服务端请求并注入 cookie(可读取),发起请求的时候读取 cookie 并带在 header 上,服务端校验时对 cookie 和 header 进行比对即可 优点:可以减轻服务端的压力 缺点:
- 如果存在 xss 漏洞,攻击者可以注入 cookie,那么防御方式失效
- 难以做子域的隔离
# Q1: 何时获取到 token
通过 token 鉴权的,token 存在 storage 中。
有个请求白名单,登录请求和鉴权请求不验证 csrfToken
如果是 xhr 异步请求,发起请求时会带上值为 token 的请求头
对于后端渲染的页面,表单中添加 hidden input; a 链则将 token 参数写在 href 链接后
如果是不进行后端渲染,登录后不刷新(接口返回token),需要遍历 dom 树插入 hidden input ,不过这种场景比较少
对于 cookie 鉴权的,后端渲染的方式就是在返回页面时将随机值插入页面,包括 form 表单和 a ,发 xhr 请求的时候通过标签去拿到随机值
也可将 cookie 再放到请求头中,后端对该请求头做加密
如果是不进行后端渲染,登录后不刷新(接口返回随机值),需要遍历 dom 树插入 hidden input ,不过这种场景比较少
服务端用 session 或 Redis 保存这个值,提交时先根据 cookie 识别对应的用户,再去找到对应的值判断是否一致
# Q2: 能否用 Access-Control-Allow-Origin 防范?
Access-Control-Allow-Origin 本质上和 CSRF 没有关系,本来就是跨域请求,且服务端能够进行处理,只是响应拿不到
# Q3: 不是说 cookie 隔离的么,为什么其他页面发请求会带上
同源策略仅仅阻止了脚本读取来自其他站点的内容.但是却没有防止脚本向其他站点发出请求。
# 重放攻击
使用 https 避免数据被拦截; https 抓包只能看到 域名端口
解决方案1: url 中加唯一id 请求的时候校验该id是否用过;需要额外空间存储 id 解决方案2:对请求的鉴权信息用时间戳进行加签,加签后的内容和时间戳一同传给服务端,服务端拿此时间戳和密钥去解签,若解签成功说明请求合法,此时可以判断下当前时间戳是否在有效时间范围内。缺点是还是有一段时间可以被重放
# 拓展阅读
前端安全系列(一):如何防止XSS攻击? (opens new window) 前端安全系列之二:如何防止CSRF攻击? (opens new window)