CSRF的背景和介绍
CSRF定义:跨站点请求伪造(英文),也称为一键攻击或会话骑行,通常缩写为CSRF或XSRF,是一种迫使用户对当前登录的Web应用程序执行无意操作的攻击方法。
简单来说,就是攻击者通过一些技术手段欺骗用户的浏览器,访问他曾经认证过的网站,进行一些操作(比如发邮件、发消息,甚至转账、购买商品等财产操作)。由于浏览器已经过身份验证,被访问的网站会将其视为真实的用户操作并执行。这就利用了web中用户认证的一个漏洞:简单的认证只能保证请求来自用户的浏览器,但不能保证请求本身是用户自愿发送的。
CSRF现状:是网络攻击,也是互联网的主要安全隐患之一。NYTimes.com(纽约时报)、Metafilter、YouTube、Gmail、百度HI都遭到过这类攻击。
比较XSS:与跨站点脚本(XSS)相比,XSS利用用户对指定网站的信任,而CSRF利用网站对用户网络浏览器的信任。
CSRF袭击的例子
大关仁在银行有存款。输入用户名和密码后,他登录该银行的网上银行,并以自己的名义发送转账请求:
http://www.bank.example/withdraw?account=daganren1 mount=999 for=daganren2
将打拐人1的999块转入打拐人2账户。通常用户登录后,系统会保存用户登录的会话值(可能是用户的手机号、账号等。).但是,如果大甘仁不小心打开了一个新的标签页,进入了黑客金莲的网站,金莲网站的页面中会嵌入以下html标签:
!DOCTYPE htmlhtml!-其他页面元素-img src=http://www.bank.example/withdraw?账号=daguanren1amount=888for=金莲宽度='0 '高度='0 '!-其他页面元素- /html此请求将附带大甘仁的会话值,高级官员的888元将成功转入金莲的账户。但是,如果打官人之前没有登录网银,而是直接打开了金莲的网站,就不会因为没有会话值而受到攻击。虽然上面的例子是get请求,但是通过post请求提交的表单也会受到攻击。
iframe style=' display : none ' name=' csrf-frame '/iframe form method=' POST ' action=' http://www . bank . example/retract ' target=' csrf-frame ' id=' csrf-form '输入类型=' hidden ' name=' account ' value=' daganrene 1 '输入类型='hidden' name='amount '输入类型=' hidden ' name=' for ' value=' Jinlian '输入类型='submit' value='submit '提交()/脚本
因此,要受到CSRF的攻击,必须同时满足两个条件:1。登录可信网站A,在本地生成Cookie。2.访问危险网站b而不注销a。
CSRF攻击的目标
在讨论如何抵抗CSRF之前,有必要弄清楚CSRF进攻的对象,也就是要保护的对象。从上面的例子可以看出,CSRF攻击是黑客借助受害者的cookie(session)欺骗服务器的信任,但是黑客无法获取cookie并且看不到cookie的内容。此外,由于浏览器同源策略的限制,黑客无法解析服务器返回的结果。因此,黑客无法从返回的结果中获得任何东西。他能做的就是向服务器发送请求,执行请求中描述的命令,直接在服务器端改变数据的值,而不是从服务器端窃取数据。因此,我们想要保护的对象是那些可以直接产生数据更改的服务,而读取数据的服务不需要受到CSRF的保护。比如银行系统的转账请求会直接改变账户的金额,会受到CSRF的攻击,需要保护。查询余额是金额的读取操作,不会改变数据。CSRF攻击无法解析服务器返回的结果,因此不需要保护。
所以增删修改需要防范CSRF攻击,而阅读不需要防范。
当前保卫CSRF的几种策略
目前业界防御CSRF攻击的策略主要有四种:-验证HTTP Referer字段;-向请求地址添加令牌并验证它;-自定义HTTP头中的属性并进行验证;-在chrome浏览器端启用SameSite cookie
1.验证HTTP引用者字段
什么是HTTP引荐者?下图是百度跳转到QQ邮箱页面的推荐人查看示意图:
可以看出,Referer是
推荐人:https://www.baidu.com/
根据HTTP协议,在HTTP头中有一个名为Referer的字段,它记录了HTTP请求的源地址。如果黑客想对银行网站进行CSRF攻击,当用户通过黑客的网站向银行发送请求时,请求的Referer值指向黑客的网站,而不是用户的网站。因此,为了抵御CSRF攻击,银行网站只需为每个转账请求验证其Referer值。如果是以www.bank.example开头的域名,则意味着请求来自银行网站本身,是合法的。如果引荐者是另一个网站,它可能是黑客的CSRF攻击,请求被拒绝。
这种方法的明显优点是简单易行。普通的网站开发者不需要担心CSRF漏洞,只需要在所有安全敏感的请求中添加一个拦截器来检查Referer的值。特别是对于当前的现有系统,没有必要改变当前系统的任何现有代码和逻辑。
然而,这种方法并不是万无一失的。Referer的值由浏览器提供。虽然HTTP协议中有明确的要求,但Referer的具体实现可能会因浏览器而异,并不能保证浏览器没有安全漏洞。验证Referer值的方法意味着安全性依赖于第三方(即浏览器),这在理论上是不安全的。事实上,对于某些浏览器,比如IE6或FF2,已经有一些方法可以篡改Referer值。如果网站www.bank.example支持IE6浏览器,黑客可以将用户浏览器的Referer值设置为以域名www.bank.example开头的地址,这样就可以通过验证,从而进行CSRF攻击。
即使使用最新的浏览器,黑客也无法篡改Referer值,这种方法仍然存在问题。由于Referer值记录了用户的访问来源,一些用户认为这样会侵犯他们的隐私权,特别是一些组织担心Referer值会将组织内部网络中的一些信息泄露给外部网络。因此,用户自己可以设置浏览器,使其在发送请求时不再提供Referer。当他们正常访问银行网站时,网站会认为是CSRF攻击,因为该请求没有Referer值,并拒绝合法用户的访问。
另外,如果Referer的判断逻辑写得不严密,也很容易被打破,比如,
const refer=request . headers . refer;如果(referer . index of(' www . bank . example ')-1){//pass }如果黑客的网站是www.bank.example.hack.com,则refer检查无效。
2.向请求地址添加令牌并验证它
CSRF攻击成功的原因是黑客可以完全伪造用户的请求,并且请求中的所有用户认证信息都存在于cookie中,因此黑客可以在不知道认证信息的情况下直接使用用户的cookie通过安全认证。要抵制CSRF,关键是在请求中放入黑客无法伪造的信息,而这些信息在cookie中是不存在的。可以将随机生成的令牌以参数的形式添加到HTTP请求中,并且可以在服务器端建立拦截器来验证该令牌。如果请求中没有令牌或令牌内容不正确,则请求可能会被视为CSRF攻击而被拒绝。
这种方法比检查引用更安全。令牌可以在用户登录并放入会话后生成,然后在每次发出请求时将令牌从会话中取出,并与请求中的令牌进行比较。然而,这种方法的难点在于如何将令牌以参数的形式添加到请求中。对于GET请求,令牌将被附加到请求地址,因此URL变成
http://url?csrftoken=tokenvalue
对于开机自检请求,请在表单末尾添加
input type=' hidden ' name=' csrftoken ' value=' token value '/此方法的缺点是很难保证令牌本身的安全性。特别是在一些论坛和其他支持用户发布自己内容的网站,黑客可以发布自己网站的地址。由于系统还会在此地址后添加令牌,黑客可以在自己的网站上获得此令牌,并立即发起CSRF攻击。为了避免这种情况,系统可以在添加令牌时添加一个判断。如果链接链接到您自己的站点,请在后面添加令牌,但如果链接指向外部网络,则不要添加令牌。但是,即使这个CSRFtoken没有以参数的形式附加到请求中,黑客的网站也可以通过Referer获得这个token值来发起csrf攻击。这就是为什么有些用户喜欢手动关闭浏览器的Referer功能。
3.自定义HTTP头中的属性并验证它们
此方法还使用令牌并对其进行验证。与前面的方法不同,令牌不是作为参数放在HTTP请求中,而是放在HTTP头的自定义属性中。使用XMLHttpRequest,您可以一次将csrftoken(HTTP头属性)添加到该类的所有请求中,并将令牌值放入其中。这样就解决了向请求中添加令牌的不便。同时,XMLHttpRequest请求的地址不会记录在浏览器的地址栏中,也不用担心令牌会通过Referer泄露给其他网站。
然而,这种方法有很大的局限性。在Ajax方法中,XMLHttpRequest请求通常用于异步页面刷新。并不是所有的请求都适合由这个类发起,而且这类请求获得的页面是浏览器无法记录的,用户前进、后退、刷新、收藏都不方便。另外,对于没有CSRF保护的遗留系统,要采用这种方法进行保护,所有的请求都要改为XMLHttpRequest请求,这几乎意味着要重写整个网站,这无疑是不可接受的。
4.在Chrome浏览器上启用SameSite cookie
下面描述如何启用SameSite cookie的设置,这非常简单。
原始Cookie的标头设置如下所示:
set-Cookie : session _ id=esadfas 325
只需在尾部添加相同的站点:
set-Cookie : session _ id=esdfas 32 e 5;SameSite
SameSite有两种模式,Lax和Strict。默认情况下启用严格模式,您可以自行指定模式:
set-Cookie : session _ id=esdfas 32 e 5;same site=StritSet-Cookie : foo=bar;SameSite=Lax
严格模式规定cookie只能由同一站点使用,不应添加到任何跨站点请求中。也就是说,A标签、表单表单和XMLHttpRequest提交的内容,只要提交到不同的站点,就不会带来cookie。
但是也有不方便的地方,比如有朋友给我发了一个已经登录的页面的链接,我点开之后,页面还是需要重新登录。
有两种处理方法。第一种是像亚马逊一样准备两种不同的饼干。第一种是维护登录状态不设置SameSite,第二种是对一些敏感操作(如购买、支付、账户设置等)严格设置SameSite。).
基于这一思想,SameSite的另一种模式应运而生:Lax模式。
宽松模式会打开一些限制,例如
alink rel=' prerender ' form method=' get ',所有这些都会带来cookie。但是,POST方法的形式,或者只要是POST、PUT、DELETE方法,都不会带cookie。但是一定要注意将重要请求模式改为POST,否则GET还是会被攻击。PS:这个方法目前只有Chrome支持。
附言
模式1通过验证HTTP Referer头信息来防止跨站点请求伪造csrf,这可以通过java中的过滤器来实现。模式2和模式3都通过向请求添加令牌来执行安全验证,这是spring security提供的csrf保护方式,从spring security 4.0开始,csrf保护默认打开。对于一个新项目,它可以有几种使用方式,这样更安全。如果它是一个完整的web程序,使用模式1修改它是很方便的,否则通过添加csrfToken,每个请求都会有很大的改变。关于春季安全csrf,请参考我的博客文章:https://www.jb51.net/article/157547.htm
以上就是本文的全部内容。希望对大家的学习有帮助,希望大家多多支持我们。