安全
1. 跨站点脚本攻击(XSS)
全称Cross Site Script
将一段恶意脚本添加到网页上,通过浏览器加载执行,从而获得 Storage 里面的隐私信息。
一般出现在同一域名下的多个 Web 应用程序,互相共享了存储对象,使得某些应用拿到了所有应用的数据
分为三类
- 反射型(Reflected XSS,非持久)
-
发生过程
- 发出请求时,XSS 恶意代码出现在 URL 参数中,作为输入提交到服务器
- 服务器响应后用 XSS 代码渲染出 HTML 页面,传回浏览器,最后浏览器解析执行了 XSS 代码
-
由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击,可能会把长的恶意 URL 用工具生成短网址,形成二次跳转,更加隐蔽
- 整个过程像一次反射,所以叫反射型 XSS
-
防御办法
- 对请求的参数进行检查,后端一定要做,发现可疑字符就拒绝
- 把请求参数渲染到 HTML 页面前,先进行转义再显示
- 使用
encodeURIComponent - 比如把
<符号转变为<
- 使用
- 设置 cookie 为 httpOnly,这样 js 就拿不到了
- 存储型(Stored XSS,持久)
-
发生过程
- 恶意脚本被攻击者上传并保存到了服务器端的数据库
- 普通用户打开网站,会从数据库中获取,然后在本地浏览器执行
- 恶意脚本就会窃取用户数据并发送到攻击者的网站
- 破坏性很强,获得了在网络上传播的能力
-
常见的场景是,黑客写下一篇包含有恶意 JS 代码的博客文章,文章发表后,所有访问该博客的用户,都会在他们的浏览器中执行这段恶意 js 代码
-
防御办法
- 对请求的参数进行检查,后端一定要做,写入数据库前进行转义和过滤危险字符
- DOM 型(也叫本地 XSS)
-
前端 JS 代码不严谨,把不可信的内容插入到了页面
- 是一种特殊的反射型,是基于 DOM 动态插入内容的一种漏洞
-
防御办法
- 用.innerHTML、.outerHTML、.appendChild、document.write()等 API 时要特别小心
- 不要把不可信的数据作为 HTML 插入到页面上
- 尽量使用.innerText、.textContent、.setAttribut()等
2. 跨站请求伪造(CSRF)
全称Cross-site request forgery
将一段“访问正式网站的脚本”添加到伪造网站上,当浏览器还存在正式 cookie 时,伪造网站就可以盗用这个 cookie 去请求正式网站,从而拿到身份操作权限
分为 GET 型和 POST 型
案例
-
受害者 Bob 在银行有一笔存款,通过对银行的网站发送请求
http://bank.example/withdraw?account=bob&amount=1000000&for=bob2可以使 Bob 把 1000000 的存款转到 bob2 的账号下。通常情况下,该请求发送到网站后,服务器会先验证该请求是否来自一个合法的 session,并且该 session 的用户 Bob 已经成功登陆。 -
黑客 Mallory 自己在该银行也有账户,他知道上文中的 URL 可以把钱进行转帐操作。Mallory 可以自己发送一个请求给银行:
http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory。但是这个请求来自 Mallory 而非 Bob,他不能通过安全认证,因此该请求不会起作用。 -
这时,Mallory 想到使用 CSRF 的攻击方式,他先自己做一个网站,在网站中放入如下代码:
src=”http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory ”,并且通过广告等诱使 Bob 来访问他的网站。当 Bob 访问该网站时,上述 url 就会从 Bob 的浏览器发向银行,而这个请求会附带 Bob 浏览器中的 cookie 一起发向银行服务器。大多数情况下,该请求会失败,因为他要求 Bob 的认证信息。但是,如果 Bob 当时恰巧刚访问他的银行后不久,他的浏览器与银行网站之间的 session 尚未过期,浏览器的 cookie 之中含有 Bob 的认证信息。这时,悲剧发生了,这个 url 请求就会得到响应,钱将从 Bob 的账号转移到 Mallory 的账号,而 Bob 当时毫不知情。等以后 Bob 发现账户钱少了,即使他去银行查询日志,他也只能发现确实有一个来自于他本人的合法请求转移了资金,没有任何被攻击的痕迹。而 Mallory 则可以拿到钱后逍遥法外。
疑问
【问】cookie 是不能跨域访问的,为什么会有 csrf 攻击?【答】浏览器会依据加载的域名附带上对应域名 cookie。就是如果用户在 a 网站登录且生成了授权的 cookies,然后访问 b 网站,b 站故意构造请求 a 站的请求,如删除操作之类的,用 script,img 或者 iframe 之类的加载 a 站这个地址,浏览器会附带上 a 站此登录用户的授权 cookie 信息,这样就构成 crsf,会删除掉当前用户的数据。
防御手段
-
验证 HTTP 头的 Referer 字段,是否是正式网站的域名开头,如果不是就拒绝,通过 request 拦截器实现。
- 但这种方法是把安全性交给浏览器保障,浏览器可能有漏洞,有些情况下 referer 还可以被伪造
-
验证 form 标签上的 crsf token 参数,是否是服务器颁发的随机 token,如果不是就拒绝,通过 request 拦截器实现。
- GET 请求就放在 url 参数中
- POST 请求就放在 form 表单中,有些麻烦,但要更安全一些。
-
验证 HTTP 头的 csrf token 字段,通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,验证原理同 2,只是更方便
-
【推荐】设置 cookie 属性的时候设置 Samesite ,限制 cookie 不能作为被第三方使用