web安全机制问题详解之二:CSRF

什么是CSRF

CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击网站执行某项操作的目的。

一个典型的CSRF攻击流程:

  • 用户登录a.com,并保留了登录凭证(cookie)
  • 攻击者引诱用户访问b.com,如,诱导性文字按钮等
  • b.com向a.com发送了一个请求:a.com/act=xx。浏览器会默认携带a.com的cookie
  • a.com接收到请求后,对请求进行验证,并确认是受害用户的凭证,误以为是用户自己发送的请求
  • a.com以用户名义执行了act=xx
  • 攻击完成,攻击者在用户不知情的情况下,冒充用户,让a.com执行了自己定义的操作

例如:

用户A浏览Gmail邮件,因好奇点击了一封“甩卖比特币,只要998”的广告邮件。打开后一片空白,随后用户A关闭了页面。但此时CSRF攻击已经完成,用户A的Gmail邮件将逐一转发到黑客的邮箱。具体是怎么发生的呢,关键在于那个空白页面的源码:

<form method="POST" action="https://mail.google.com/mail/h/ewt1jmuj4ddv/?v=prf" enctype="multipart/form-data"> 
    <input type="hidden" name="cf2_emc" value="true"/> 
    <input type="hidden" name="cf2_email" value="hacker@hakermail.com"/> 
    .....
    <input type="hidden" name="irf" value="on"/> 
    <input type="hidden" name="nvp_bu_cftb" value="Create Filter"/> 
</form> 
<script> 
    document.forms[0].submit();
</script>复制代码

这个页面只要一打开就会向Gmail发送一个post请求。请求中,执行了‘Create Filter’命令(自动转发邮件),将所有邮件转发到黑客邮箱hacker@hakermail.com。由于A刚登陆了Gmail,用户登录凭证被保存在cookie中,所以这个空白页发出的post请求就携带了登陆证明,于是成功给用户A配置了过滤器。黑客可以查看所有用户A的邮件,包括一些敏感信息:邮箱验证码等等。此事件原型是2007年Gmail的CSRF漏洞:www.davidairey.com/google-Gmai…。目前此漏洞已修复。

几种常见的CSRF攻击

GET类型攻击:http请求时,敏感参数跟在url后面,攻击者很容易获取并发送包含受害者信息的跨域请求。

POST类型攻击:如上案列所示。

链接类型攻击:页面中注入恶意链接,诱导用户点击跳转。

防护策略

据上所示,CSRF通常是由第三方网站发起,因此可以通过增强自身网站的安全性来防御:

  • 同源策略
  • token验证

同源检测

同源策略上分为两部分:一是http请求接口的同源,还有一个是cookie的domain属性的同源。

1. http请求,可以使用origin header、referer header确定来源域名。

在部分请求中,请求的header中会携带origin字段,代表请求的域名;也有不存在origin的情况,IE11对同源的定义有别于其他浏览器,还有一个就是302重定向之后origin不包含在重定向的请求中,因为重定向请求是定向到新的服务器,避免泄露origin信息。

http请求header中还有另外一个记录该请求来源地址的属性referer。referer值是由浏览器提供的,不可排除浏览器自身安全性问题,和部分情况下攻击者隐藏甚至篡改自己请求的referer。在同源策略下,可以把referer属性设置成same-origin,对于同源的额链接和引用会发送referer,对于跨域则不携带referer。

设置referer的三种方法:在csp设置;页面头部增设meta标签;a标签增加referer属性

<a href="https://www.baidu.com/" ref="noreferrer">跳到百度</a>复制代码

但是,在以下情况下referer没有或者不可信:

  • IE6、7使用window.location.href=url进行界面跳转,会丢失referer
  • IE6、7使用window.open,也会丢失referer
  • https跳到http,所有浏览器都会丢失referer
  • 点击flash到达另外一个网站时,referer不可信

2. 在浏览器种下cookie时,若明确cookie的domain属性(一级域名或是子域名),即仅在domain指定的域下的接口才会自动携带cookie,可以解决部分跨域问题,但仍不能避免攻击者伪造的域名和网站同域(本地服务器proxy代理请求时)。还可以设置cookie为Httponly,这样cookie只能在请求中被携带,无法用document.cooke读取、修改。

token验证

这里的token验证也有两种,一种是CSRF token的加解密校验,还有一个是双重Cookie验证。

1. CSRF token

用户打开页面时,服务器会个每个用户生成唯一的token,这个token是经过精密算法对数据进行加密,一般包括随机字符串和时间戳。token会存在服务器的session中。页面提交的请求都会携带这个token,当服务器拿到token后用相应解密算法得到时间戳、及加密字符串,再和服务器session中存储的token信息作比较来判断该请求的有效性,这类token一般是随机字符串。

分布式校验

在大型网站中,使用session存储token会带来很大压力。访问单台服务器session是同一个。但是现在的大型网站中,我们的服务器通常不止一台,可能是几十台甚至几百台之多,甚至多个机房都可能在不同的省份,用户发起的HTTP请求通常要经过像Ngnix之类的负载均衡器之后,再路由到具体的服务器上,由于Session默认存储在单机服务器内存中,因此在分布式环境下同一个用户发送的多次HTTP请求可能会先后落到不同的服务器上,导致后面发起的HTTP请求无法拿到之前的HTTP请求存储在服务器中的Session数据,从而使得Session机制在分布式环境下失效,因此在分布式集群中CSRF Token需要存储在Redis之类的公共存储空间。

目前的解决办法就是采用Encrypted Token Pattern方式,计算出一个结果,而不是随机字符串。这样就无需将token存储在session中,只需要在拿到token的时候再计算一次就行。

Token是一个比较有效的CSRF防护方法,只要页面没有XSS漏洞泄露Token,那么接口的CSRF攻击就无法成功。其次,验证码和密码其实也有CSRF token的作用。

2. 双重Cookie验证

双重Cookie采用以下流程:

  • 在用户访问网站页面时,向请求域名注入一个Cookie,内容为随机字符串(例如csrfcookie=v8g9e4ksfhw)。
  • 在前端向后端发起请求时,取出Cookie,并添加到URL的参数中(接上例POST https://www.a.com/comment?csrfcookie=v8g9e4ksfhw)。
  • 后端接口验证Cookie中的字段与URL参数中的字段是否一致,不一致则拒绝。

此方法相对于CSRF Token就简单了许多。可以直接通过前后端拦截的的方法自动化实现。后端校验也更加方便,只需进行请求中字段的对比,而不需要再进行查询和存储Token。

当然,此方法并没有大规模应用,其在大型网站上的安全性还是没有CSRF Token高,原因我们举例进行说明。

由于任何跨域都会导致前端无法获取Cookie中的字段(包括子域名之间),于是发生了如下情况:

  • 如果用户访问的网站为www.a.com,而后端的api域名为api.a.com。那么在www.a.com下,前端拿不到api.a.com的Cookie,也就无法完成双重Cookie认证。
  • 于是这个认证Cookie必须被种在a.com下,这样每个子域都可以访问。
  • 任何一个子域都可以修改a.com下的Cookie。
  • 某个子域名存在漏洞被XSS攻击(例如upload.a.com)。虽然这个子域下并没有什么值得窃取的信息。但攻击者修改了a.com下的Cookie。
  • 攻击者可以直接使用自己配置的Cookie,对XSS中招的用户再向www.a.com下,发起CSRF攻击。

参考:前端安全系列(二):如何防止CSRF攻击?


转载于:https://juejin.im/post/5c9206e4f265da61003d2eb6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值