CSRF的全称是Cross-site request forgery跨站点请求伪造,也称为一键攻击或会话劫持,它是对网站的一种恶意利用,主要利用的是已受权用户对于站点的信任,无辜的最终用户被攻击者诱骗提交了他们不但愿的Web请求。 恶意网站能够经过多种方式来发送此类命令。 例如,特制的图像标签,隐藏的表单和JavaScript XMLHttpRequests均可以在用户不交互甚至不知情的状况下工做。javascript
若是发生了CSRF攻击,可能致使客户端或服务器数据意外泄漏,会话状态更改或者修改用户的信息。html
在CSRF的恶意攻击中,攻击者的目标是让被攻击者在不知不觉中向有权限访问的网站提交恶意的web请求。经过对该请求进行精心的设计,使其包含URL参数,Cookie和其余对处理该请求的Web服务器而言正常显示的数据。经过保存在用户Web浏览器中的cookie进行身份验证的用户可能会在不知不觉中将HTTP请求发送到信任该用户的站点,从而致使没必要要的操做。java
为何会有这样的攻击呢?由于对于web浏览器来讲,它们将在发送给该域的任何Web请求中自动且无形地包含给定域使用的任何cookie。 CSRF攻击利用了此属性,由于浏览器发出的任何Web请求都将自动包含受害者登陆网站时建立的任何cookie(包括会话cookie和其余cookie)。若是用户被诱骗经过浏览器无心中提交了请求,这些自动包含的cookie将使伪造也可以经过目标服务器的认证,从而产生恶意攻击。web
为了生成这样的攻击URL,恶意攻击者须要构造一个能够被执行的web请求,好比在目标页面上更改账户密码。攻击者能够将该连接嵌入攻击者控制范围内的页面上。好比它能够嵌入到发送给受害者的电子邮件中的html图像标签中,当受害者打开其电子邮件时,该图像会自动加载。一旦受害者单击了连接,他们的浏览器将自动包含该网站使用的全部cookie,并将请求提交到Web服务器。 Web服务器将会执行该恶意请求。跨域
早在2001年,就有人开始使用它来进行攻击了。不过由于攻击使用的是用户本身的IP地址,看起来就像是用户本身的一个正常的请求,因此不多有直接的攻击证据。目前知道的比较有名的CSRF攻击以下:浏览器
2006年Netflix爆出了众多CSRF漏洞,攻击者能够更改受害者的帐户收货地址,从而为攻击者本身来购买商品。
YouTube在2008年也受到了CSRF的攻击,这使得任何攻击者都几乎能够执行任何用户的全部操做。
McAfee Secure也曾经受到过CSRF的攻击,它容许攻击者更改公司系统。
2018年,一些路由器也受到了CSRF的攻击,从而可以修改路由器的DNS设置。服务器
要想达成CSRF攻击是须要必定的条件的,事实上CSRF攻击也并非一个很简单的事情,必须知足下面的条件:cookie
由于web浏览器对不一样的HTTP请求处理方式是不一样的,因此针对CSRF攻击的防范跟HTTP请求的方法相关。框架
在HTTP GET中,使用CSRF攻击很是简单,好比将攻击URL带入IMG标签就会自动加载。可是,根据HTTP规范,GET方法不该该被用于修改数据。使用GET进行更新数据操做的应用程序应切换到HTTP POST或使用反CSRF保护。ide
CSRF的HTTP POST漏洞取决于使用状况:
在最简单的POST形式中,数据编码为查询字符串(field1 = value1&field2 = value2),可使用简单的HTML形式轻松实现CSRF攻击,这就意味着必须采起反CSRF措施。
若是以其余任何格式(JSON,XML)发送数据,标准方法是使用XMLHttpRequest发出POST请求,并经过同源策略(SOP)和跨域资源共享(CORS)防止CSRF攻击。
其余HTTP方法(PUT,DELETE等)只能使用具备同源策略(SOP)和跨域资源共享(CORS)来防止CSRF的XMLHttpRequest请求;可是,在使用Access-Control-Allow-Origin:*标头明确禁用它们的网站上,这些措施将无效。
下面咱们来具体讲解几个防范CSRF的技巧
STP的全称是Synchronizer token pattern。也就是说在全部的HTML表单上包含一个隐藏的token字段,token是能够由不少种方法来生成,只要保证其随机性就好了。由于攻击者没法预测到这个token的值,因此没法进行CSRF攻击。好比下面的代码:
<input type="hidden" name="csrfmiddlewaretoken" value="KbyUmhTLMpYj7CD2di7JKP1P3qmLlkPt" />
STP是兼容性最好的,由于它仅依赖HTML,可是每一个请求都带上token会增长程序的复杂性, 因为token是惟一且不可预测的,所以还会强制执行适当的事件顺序,这会引起一些可用性的问题(例如用户打开多个选项卡)。 能够经过使用每一个会话CSRF令牌而不是每一个请求CSRF令牌来放宽它。
若是web应用程序主要使用javascript来进行交互的话,能够考虑使用这种方式。
在初次访问web服务的时候,会在cookie中设置一个随机令牌,该cookie没法在跨域请求中访问:
Set-Cookie: csrf_token=i8XNjC4b8KVok4uw5RftR38Wgp2BFwql; Expires=Thu, 23-Jul-2015 10:25:33 GMT; Max-Age=31449600; Path=/; Domain=.wikipedia.org; SameSite=Lax; Secure
在客户端运行javascript的时候,从cookie中读取这个token值,并将其复制到随每一个事务请求发送的自定义HTTP标头中
X-Csrftoken:i8XNjC4b8KVok4uw5RftR38Wgp2BFwql
服务器验证令牌的存在和完整性。由于从恶意文件或电子邮件运行的JavaScript没法成功读取cookie值以复制到自定义标头中。即便将csrf token cookie与恶意请求一块儿自动发送,服务器任然须要有效的X-Csrf-Token头。
这项技术已经被不少框架实现了,好比Django 和AngularJS,由于令牌在整个用户会话中保持不变,因此它能够与AJAX应用程序很好地协同工做。
注意,使用这项技术,必须确保同源政策。
这个方法与cookie-to-header方法相似,但不涉及JavaScript,站点能够将CSRF令牌设置为cookie,也能够将其做为每一个HTML表单中的隐藏字段插入。 提交表单后,站点能够检查cookie令牌是否与表单令牌匹配。 同源策略可防止攻击者在目标域上读取或设置Cookie,所以他们没法以其精心设计的形式放置有效令牌。
与同步器模式相比,此技术的优点在于不须要将令牌存储在服务器上。
当服务器设置cookie时,能够包含一个附加的“ SameSite”属性,指示浏览器是否将cookie附加到跨站点请求。 若是将此属性设置为“strict”,则cookie仅在相同来源的请求中发送,从而使CSRF无效。 可是,这须要浏览器识别并正确实现属性,而且还要求cookie具备“Secure”标志。
浏览器自己能够经过为跨站点请求提供默认拒绝策略,来阻止CSRF。好比Mozilla Firefox的RequestPolicy或者Firefox和Google Chrome / Chromium 的uMatrix之类。可是,这可能会严重干扰许多网站的正常运行。
有些浏览器扩展程序如CsFire扩展(也适用于Firefox)能够经过从跨站点请求中删除身份验证信息,从而减小对正常浏览的影响。
本文已收录于 http://www.flydean.com/csrf/
最通俗的解读,最深入的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注个人公众号:「程序那些事」,懂技术,更懂你!