CSRF是什么?
Cross-site request forgery 简称为“CSRF”,在CSRF的攻击场景中攻击者会伪造一个请求(这个请求一般是一个链接),然后诱骗目的用户进行点击,用户一旦点击了这个请求,整个攻击就完成了。所以CSRF攻击也成为"one click"攻击。 许多人搞不清楚CSRF的概念,甚至有时间会将其和XSS肴杂,更有甚者会将其和越权问题等量齐观,这都是对原理没搞清楚导致的。
简单的说,是攻击者通过一些技术手段诱骗用户的欣赏器去访问一个本身以前认证过的站点并运行一些操作(如发邮件,发消息,甚至财产操作(如转账和购买商品))。因为欣赏器之前认证过,所以被访问的站点会以为这是真正的用户操作而去运行。
Session工作原理
关于欣赏器缓存,cookie , session:http://www.cnblogs.com/yigeqi/p/6274602.html
明确Cookie和Session机制:https://www.cnblogs.com/andy-zhou/p/5360107.html
深入明确欣赏器会话机制(session && cookie):https://blog.csdn.net/xi_2130/article/details/51361494
cookie 和session 的区别详解:https://www.cnblogs.com/shiyangxt/articles/1305506.html
Cookie和Session详解:https://blog.csdn.net/gaoyong_stone/article/details/79524321
假如我把欣赏器的cookie禁用了,session还能正常工作吗?
答案是否定的,我在这边举个简单的例子帮助明确session。
好比我买了一张高尔夫俱乐部的会员卡,俱乐部给了我一张带有卡号的会员卡。我能享受哪些权利(好比我是高级会员卡可以打19洞和后付费喝饮料,而初级会员卡只能在训练场挥杆)以及我的个人资料都是保存在高尔夫俱乐部的数据库里的。我每次去高尔夫俱乐部只需要出示这张高级会员卡,俱乐部就知道我是谁了,并且为我服务了。
这里我们的高级会员卡卡号 = 保存在cookie的sessionid; 而我的高级会员卡权利和个人信息就是服务端的session对象了。
我们知道http请求是无状态的,也就是说每次http请求都是独立的无关之前的操作的,但是每次http请求都会将本域下的所有cookie作为http请求头的一部分发送给服务端,所以服务端就根据请求中的cookie存放的sessionid去session对象中找到该会员资料了。
固然session的保存方法多种多样,可以保存在文件中,也可以内存里,考虑到分布式的横向扩展我们还是建议把它保存在第三方媒介中,好比redis大概mongodb。
我们明确了session的工作机制后,CSRF也就很轻易明确了。CSRF攻击就相当于恶意用户A复制了我的高级会员卡,哪天恶意用户A也可以拿着这张假冒的高级会员卡去高尔夫俱乐部打19洞,享受鲜味的饮料了,而我在月尾就会收到高尔夫俱乐部的账单!
原理及过程
因为CSRF攻击,会重复利用用户的 Cookie,而说到 Cookie,就得先从 HTTP 协议开始讲起。
HTTP协议
无记忆性
HTTP是一种无状态协议,即服务器不会保留与客户交易时的状态。
用户A在很短的时间间隔内向Web服务器发送了两次同样的请求,服务器并不会因为已经相应了该请求一次就不对第二次请求进行相应,因为服务器并不知道已经相应过一次该请求。
假设用户在网站A的某一个页面上已经完成了登录操作,当在该网站的另一个页面上执行的操作需要验证用户登录的时间仍然需要用户再次登录,因为HTTP并不知道你已经登录了,它不会维持你的登录状态。
因为要多次登录太过麻烦,为了让服务器能够记取用户引入了Cookle机制
Cookie 机制
当用户访问站点的时间,站点会为该用户分配一个 Cookie 值,站点使用该 Cookie 值来标志用户,当用户欣赏器接受到包罗 Cookie 值得数据包后,会将 Cookie 得值取出,存放到欣赏器中,随后欣赏器会在发往该站点得数据包中自动得填充该 Cookie 值。Cookie 的值的填充是欣赏器的行为。
当欣赏器自动完成Cookie的填充,目的网站会误认为该数据包就是管理员发送的,会以管理员的权限进行相关的操作。
第一方和第三方cookie概念
Cookie是一个域服务器存储在欣赏器中的一小段数据块,只能被这个域访问,谁设置则谁访问。- 第一方Cookie:比如,访问www.a.com这个网站,这个网站设置了一个Cookie,这个Cookie也只能被www.a.com这个域下的网页读取。
- 第三方Cookie:比如,访问www.a.com这个网站,网页里有用到www.b.com网站的一张图片,浏览器在www.b.com请求图片的时候,www.b.com设置了一个Cookie,那这个Cookie只能被www.b.com这个域访问,反而不能被www.a.com这个域访问,因为对我们来说,我们实际是在访问www.a.com这个网站被设置了一个www.b.com这个域下的Cookie,所以叫第三方Cookie。
复制代码 CSRF原理:
- 1、客户端通过账户密码登录访问网站A。
- 2、网站A验证客户端的账号密码,成功则生成一个sessionlD,并返回给客户端存储在浏览器中。
- 3、该客户端Tab—个新页面访问了网站B。
- 4、网站B自动触发要求该客户端访问网站A。(即在网站B中有链接指向网站A)
- 5、客户端通过网站B中的链接访问网站A。(此时携带有合法的SessionID进行访问站A的)
- 6、此时网站A只需检验sessionIlD是否合法,合法则执行相应的操作。(因此具体啥工具就得看链接,以及网站B要求访问时携带的数据)
复制代码
简而言之: 通过访问恶意网址,恶意网址返回来js自动执行访问你之前登陆的网址,因为你已经登录了,所以再次访问将会携带cookie,因为服务器只认有没有cookie,无法区分是不是用户正常的访问,所以会诱骗服务器,造成伤害/
要完成一次CSRF攻击,受害者必须依次完毕两个步骤:- 登录受信任站点A,并在本地生成Cookie。
- 在不登出A的情况下,访问危急站点B。
- 站点 A 没有做任何 CSRF 防御
复制代码 CSRF与XSS的区别
- CSRF:属于业务逻辑漏洞,在服务器看来,所有请求都是合法正常的
- XSS、SQL注入等:都是属于技术漏洞
- XSS是基于客户信任服务器,而CSRF是基于服务器信任客户(经过身份验证的)
场景需求:
小黑想要修改明白在购物网站www.xx.com上填写的会员地址。
先看下明白是怎样修改本身的暗码的:
登录---修改会员信息,提交请求---修改成功。
所以小黑想要修改明白的信息,他需要拥有:1,登录权限 2,修改个人信息的请求。
但是明白又不会把本身xxx网站的账号暗码告诉小黑,那小黑怎么办?
于是他本身跑到www.xx.com上注册了一个本身的账号,然后修改了一下本身的个人信息(好比:E-mail地址),他发现修改的请求是:
【http://www.xxx.com/edit.php?email=xiaohei@88.com&Change=Change】
于是,他实行了这样一个操作:把这个链接伪装一下,在小白登录xxx网站后,诱骗他进行点击,小白点击这个链接后,个人信息就被修改了,小黑就完成了攻击目的。
为啥小黑的操作能够实现呢。有如下几个关键点:
1.www.xxx.com这个网站在用户修改个人的信息时没有过多的校验,导致这个请求轻易被伪造;
---因此,我们判断一个网站是否存在CSRF漏洞,其实就是判断其对关键信息(好比暗码等敏感信息)的操作(增编削)是否轻易被伪造。
2.小白点击了小黑发给的链接,并且这个时间小白刚好登录在购物网上;
---假如小白安全意识高,不点击不明链接,则攻击不会成功,又大概纵然小白点击了链接,但小白此时并没有登录购物网站,也不会成功。
---因此,要成功实行一次CSRF攻击,需要“天时,地利,人和”的条件。
固然,假如小黑事先在xxx网的首页假如发现了一个XSS漏洞,则小黑可能会这样做: 诱骗小白访问埋伏了XSS脚本(偷取cookie的脚本)的页面,小白中招,小黑拿到小白的cookie,然后小黑顺利登录到小白的背景,小黑本身修改小白的相关信息。
---所以跟上面比一下,就可以看出CSRF与XSS的区别:CSRF是借用户的权限完成攻击,攻击者并没有拿到用户的权限,而XSS是直接偷取到了用户的权限,然后实行破坏。
因此,网站假如要防止CSRF攻击,则需要对敏感信息的操作实行对应的安全步伐,防止这些操作出现被伪造的情况,从而导致CSRF。好比:
--对敏感信息的操作增加安全的token;
--对敏感信息的操作增加安全的验证码;
--对敏感信息的操作实行安全的逻辑流程,好比修改暗码时,需要先校验旧暗码等。
怎样判断有CSRF漏洞?
1、最简单的方法就是抓取一个正常请求的数据包,假如没有Referer字段和token,那么极有可能存在CSRF漏洞。
2、假如有Referer字段,但是去掉Referer字段后再重新提交,假如该提交还有用,那么基本上可以确定存在CSRF漏洞。
3、随着对CSRF漏洞研究的不断深入,不断涌现出一些专门针对CSRF漏洞进行检测的工具,如CSRFTester,CSRF Request Builder等。以CSRFTester工具为例,CSRF漏洞检测工具的测试原理如下:
使用CSRFTester进行测试时,首先需要抓取我们在欣赏器中访问过的所有链接以及所有的表单等信息,然后通过在CSRFTester中修改相应的表单等信息,重新提交,这相当于一次伪造客户端请求。
假如修改后的测试请求成功被网站服务器接受,则说明存在CSRF漏洞,固然此款工具也可以被用来进行CSRF攻击。
怎样防御CSRF漏洞
CSRF攻击防御的重点是利用cookie的值只能被第一方读取,无法读取第三方的cookie值。
- 验证码;
- 验证 HTTP Referer 字段;
- 在请求地址中添加 token 并验证;
- 在 HTTP 头中自定义属性并验证;
复制代码 验证码
验证码被认为是对抗CSRF攻击最简洁而有用的防御方法。
CSRF攻击的过程,通常是在用户不知情的情况下构造了网络请求。而验证码,则强制用户必须与应用进行交互,才能完成终极请求。因此在通常情况下,验证码能够很好地遏制CSRF攻击。
但是验证码并非万能。许多时间,出于用户体验考虑,网站不能给所有的操作都加上验证码。因此,验证码只能作为防御CSRF的一种辅助手段,而不能作为最主要的解决方案。
验证 HTTP Referer 字段
根据 HTTP 协议,在 HTTP 头中有一个字段叫Referer,它记载了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求来自于同一个网站,好比需要访问 :- http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory
复制代码 用户必须先登陆 bank.example,然后通过点击页面上的按钮来触发转账变乱。
这时,该转帐请求的 Referer 值就会是转账按钮地点的页面的 URL,通常是以 bank.example 域名开头的地址。而假如黑客要对银行网站实行 CSRF 攻击,他只能在他本身的网站构造请求,当用户通过黑客的网站发送请求到银行时,该请求的 Referer 是指向黑客本身的网站。
因此,要防御 CSRF 攻击,银行网站只需要对于每一个转账请求验证其 Referer 值,假如是以 bank.example 开头的域名,则说明该请求是来自银行网站本身的请求,是合法的。假如 Referer 是其他网站的话,则有可能是黑客的 CSRF 攻击,拒绝该请求。
这种方法的显而易见的好处就是简单易行,网站的普通开发职员不需要操心 CSRF 的漏洞,只需要在末了给所有安全敏感的请求统一增加一个拦截器来检查 Referer 的值就可以。特别是对于当前现有的系统,不需要改变当前系统的任何已有代码和逻辑,没有风险,非常便捷。
然而,这种方法并非万无一失。Referer 的值是由欣赏器提供的,固然 HTTP 协议上有明确的要求,但是每个欣赏器对于 Referer 的具体实现可能有差别,并不能保证欣赏器自身没有安全漏洞。
使用验证 Referer 值的方法,就是把安全性都依靠于第三方(即欣赏器)来保障,从理论上来讲,这样并不安全。
事实上,对于某些欣赏器,好比 IE6 或 FF2,目前已经有一些方法可以篡改 Referer 值。假如 bank.example 网站支持 IE6 欣赏器,黑客完全可以把用户欣赏器的 Referer 值设为以 bank.example 域名开头的地址,这样就可以通过验证,从而进行 CSRF 攻击。
即便是使用最新的欣赏器,黑客无法篡改 Referer 值,这种方法仍然有问题。因为 Referer 值会记载下用户的访问来源,有些用户认为这样会侵犯到他们本身的隐私权,特别是有些组织担心 Referer 值会把组织内网中的某些信息泄露到外网中。
因此,用户本身可以设置欣赏器使其在发送请求时不再提供 Referer。当他们正常访问银行网站时,网站会因为请求没有 Referer 值而认为是 CSRF 攻击,拒绝合法用户的访问。
在请求地址中添加token字段并验证
什么是token?
作为计算机术语时,是“令牌”的意思。Token是服务端天生的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器天生一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和暗码
token产生背景
HTTP 是一种没有状态的协议,也就是它并不知道是谁是访问应用。这里我们把用户当作是客户端,客户端使用用户名还有暗码通过了身份验证,不外下回这个客户端再发送请求时间,还得再验证一下。
token用来干嘛的?
使用token机制的身份验证方法,在服务器端不需要存储用户的登录记载。
大概的流程:
1️⃣客户端使用用户名和暗码请求登录。
2️⃣服务端收到请求,验证用户名和暗码。
3️⃣验证成功后,服务端会天生一个token,然后把这个token发送给客户端。
4️⃣客户端收到token后把它存储起来,可以放在cookie大概Local Storage(当地存储)里。
5️⃣客户端每次向服务端发送请求的时间都需要带上服务端发给的token。
6️⃣服务端收到请求,然后去验证客户端请求里面带着token,假如验证成功,就向客户端返回请求的数据。
token是怎样防御CSRF攻击的?
CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 cookie 中,因此黑客可以在不知道这些验证信息的情况下直接利用用户本身的 cookie 来通过安全验证。
要抵御 CSRF关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。
可以在 HTTP 请求中以参数的情势加入一个随机产生的 token,并在服务器端创建一个拦截器来验证这token,假如请求中没有 token 大概 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。
这种方法要比检查 Referer要安全一些,token 可以在用户登陆后产生并放于 session 之中,然后在每次请求时把 token 从 session 中拿出,与请求中的 token 进行比对,但这种方法的难点在于怎样把 token 以参数的情势加入请求。
对于 GET 请求,token 将附在请求地址之后,这样 URL 就变成 http://url?csrftoken=tokenvalue。 而对于 POST 请求来说,要在 form 的末了加上 ,这样就把 token 以参数的情势加入请求了。
但是,在一个网站中,可以接受请求的地方非常多,要对于每一个请求都加上 token 是很麻烦的,并且很轻易遗漏,通常使用的方法就是在每次页面加载时,使用 javascript 遍历整个 dom 树,对于 dom 中所有的 a 和 form 标签后加入 token。
这样可以解决大部分的请求,但是对于在页面加载之后动态天生的 html 代码,这种方法就没有作用,还需要程序员在编码时手动添加 token。
该方法还有一个缺点是难以保证 token 本身的安全。特别是在一些论坛之类支持用户本身发表内容的网站,黑客可以在上面发布本身个人网站的地址。由于系统也会在这个地址后面加上 token,黑客可以在本身的网站上得到这个 token,并立刻就可以发动 CSRF 攻击。
为了避免这一点,系统可以在添加 token 的时间增加一个判断,假如这个链接是链到本身本站的,就在后面添加 token,假如是通向外网则不加。
不外,纵然这个 csrftoken 不以参数的情势附加在请求之中,黑客的网站也同样可以通过 Referer 来得到这个 token 值以发动 CSRF 攻击。这也是一些用户喜好手动关闭欣赏器 Referer 功能的缘故起因。
在 HTTP 头中自界说属性并验证
这种方法也是使用 token 并进行验证,和上一种方法差别的是,这里并不是把 token 以参数的情势置于 HTTP 请求之中,而是把它放到 HTTP 头中自界说的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入此中。
这样解决了上种方法在请求中加入 token 的未便,同时,通过XMLHttpRequest 请求的地址不会被记载到欣赏器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。
然而这种方法的局限性非常大,XMLHttpRequest 请求通常用于 Ajax 方法中对于页面局部的异步刷新,并非所有的请求都适实用这个类来发起,而且通过该类请求得到的页面不能被欣赏器所记载下,从而进行进步,后退,刷新,收藏等操作,给用户带来未便。
别的,对于没有进行 CSRF 防护的遗留系统来说,要采用这种方法来进行防护,要把所有请求都改为 XMLHttpRequest 请求,这样险些是要重写整个网站,这代价无疑是不能接受的。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |