CSRF
CSRF是Cross Site Request Forgery的缩写,翻译过来就是跨站请求伪造。html
- 跨站:顾名思义,就是从一个网站到另外一个网站。
- 请求:即HTTP请求。
- 伪造:在这里能够理解为仿造、假装。
- 综合起来的意思就是:从一个网站A中发起一个到网站B的请求,而这个请求是通过了假装的,假装操做达到的目的就是让请求看起来像是从网站B中发起的,也就是说,让B网站所在的服务器端误觉得该请求是从本身网站发起的,而不是从A网站发起的。
- CSRF 攻击是黑客借助受害者的 cookie 骗取服务器的信任,可是黑客并不能拿到 cookie,也看不到 cookie 的内容。另外,对于服务器返回的结果,因为浏览器同源策略的限制,黑客也没法进行解析。所以,黑客没法从返回的结果中获得任何东西,他所能作的就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据。因此,咱们要保护的对象是那些能够直接产生数据改变的服务,而对于读取数据的服务,则不须要进行 CSRF 的保护。
原理

图片来源: CSRF攻击原理以及nodejs的实现和防护node
从上图能够看出,要假装成从A网站发起请求,必须依次完成两个步骤:web
1.登陆受信任网站A,并在本地生成Cookie。跨域
2.在不登出A的状况下,访问危险网站B。
浏览器
- 之因此要假装成从A网站发起,是由于Cookie是不能跨域发送的。结合上面这个例子来讲就是:若是从A网站直接发送请求到B网站服务器的话,是没法将A网站中产生的Cookie一块儿发给B服务器的。
- 为何要发送Cookie呢?这是由于服务器在用户登陆后会将用户的一些信息放到Cookie中返回给客户端,而后客户端在请求一些须要认证的资源的时候会把Cookie一块儿发给服务器,服务器经过读取Cookie中的信息来进行用户认证,认证经过后才会作出正确的响应。
- B网站访问A网站服务器的一些须要认证的资源的时候,若是没有Cookie信息,服务器是拒绝访问的,那么B网站就没法进行恶意操做。而伪形成AB网站的请求,就能够将A网站的Cookie一块儿发到A服务器,这个时候就服务器就认为该请求是合法的,就会给出正确的响应,这个时候,B网站就达到目的了。
危害
攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF可以作的事情包括:以你名义发送邮件,发消息,盗取你的帐号,甚至于购买商品,虚拟货币转帐......形成的问题包括:我的隐私泄露以及财产安全。安全
如何防止CSRF攻击
CSRF攻击之因此可以成功,是由于黑客能够彻底伪造用户请求,该请求中全部的用户验证信息都是存在于cookie中,所以黑客能够在不知道这些验证信息的状况下直接利用用户的cookie来经过安全验证。要抵御CSRF,关键在于在请求中放入黑客没法伪造的信息。服务器
对于关键操做使用post方法:
如今的浏览器出于安全考虑,默认都作了必定的限制,form标签发送到其余网站的请求会被拦截cookie
使用验证码:
强制用户必须与应用进行交互,才能完成最终的请求。例如:用户的每次提交表单行为都须要填写一个验证码session
在请求地址中添加token并验证 Anti CSRF Token
- 服务端在收到路由请求时,生成一个随机数,在渲染请求页面时把随机数埋入页面(通常埋入 form 表单内,<input type="hidden" name="_csrf_token" value="xxxx">)
- 服务端设置setCookie,把该随机数做为cookie或者session种入用户浏览器
- 当用户发送 GET 或者 POST 请求时带上_csrf_token参数(对于 Form 表单直接提交便可,由于会自动把当前表单内全部的 input 提交给后台,包括_csrf_token)
- 后台在接受到请求后解析请求的cookie获取_csrf_token的值,而后和用户请求提交的_csrf_token作个比较,若是相等表示请求是合法的。
注意:post
- Token 最好保存在 Session 中。假如 Token 保存在 Cookie 中,用户浏览器开了不少页面(同一页面打开了屡次)。在一些页面 Token 被使用消耗掉后新的Token 会被从新种入,但那些老的 Tab 页面对应的 HTML 里仍是老 Token。这会让用户以为为啥几分钟前打开的页面不能正常提交
- 尽可能少用 GET。假如攻击者在咱们的网站上传了一张图片,用户在加载图片的时候其实是向攻击者的服务器发送了请求,这个请求会带有referer表示当前图片所在的页面的 url。 而若是使用 GET 方式接口的话这个 URL 就形如:
https://xxxx.com/gift?giftId=...
,那至关于攻击者就获取了_csrf_token,短期内可使用这个 token 来操做其余 GET 接口。
- 因为用户的Cookie很容易因为网站的XSS漏洞而被盗取,因此这个方案必需要在没有XSS的状况下才安全。
检测Referer:
Referer,根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该HTTP请求的来源地址。服务器经过检查Referer的值,若是判断
出Referer并不是本站页面,而是一个外部站点的页面,那么咱们就能够判断出这个请求是非法的
这个方法是实现防止图片盗链的原理
- 优势:这种方法的显而易见的好处就是简单易行,网站的普通开发人员不须要操心 CSRF 的漏洞,只须要在最后给全部安全敏感的请求统一增长一个拦截器来检查 Referer 的值就能够。特别是对于当前现有的系统,不须要改变当前系统的任何已有代码和逻辑,没有风险,很是便捷。
- 缺点:Referer 的值是由浏览器提供的,虽然 HTTP 协议上有明确的要求,可是每一个浏览器对于 Referer 的具体实现可能有差异,并不能保证浏览器自身没有安全漏洞。使用验证 Referer 值的方法,就是把安全性都依赖于第三方(即浏览器)来保障,从理论上来说,这样并不安全。对于某些低版本浏览器,目前已经有一些方法能够篡改 Referer 值
在HTTP头中自定义属性
这种方法也是使用token并进行验证,和上一种方法不一样的是,这里并非把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。经过 XMLHttpRequest 这个类,能够一次性给全部该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。
参考:
对CSRF(跨站请求伪造)的理解
浅谈CSRF攻击方式
XSS跨站脚本攻击与CSRF跨站请求伪造攻击的学习总结。\
CSRF攻击原理以及nodejs的实现和防护
CSRF 攻击的应对之道