CSRF

795 阅读3分钟

1. 什么是CSRF?

CSRF,cross site request forgery,跨站请求伪造。CSRF又称为“one click attack”或者“session riding”。它是攻击者通过诱导用户点击或者加载页面等方式来冒用用户身份向服务器发出请求,从而实施某些非法操作的一种攻击手段。

2. 产生CSRF的原因是什么?

  • 页面存在容易被攻击者诱导的操作。比如,转账,修改邮箱或者密码等。
  • 在执行数据操作之前,服务器只使用基于cookie的单一session机制来验证用户身份的合法性。
  • 客户端发往服务端的请求参数名的语义明确参数值是可预测的

以上的三个原因也是发起csrf的先决条件。当这三个条件都具备了,那么攻击者就可以根据社会工程学的一些知识来传播恶意链接或者邮件来诱导用户去访问。不管用户是直接还是间接的触发,浏览器都会发出CSRF请求。因为是请求是发往同源的网站,所以浏览器会默认在请求头上附带本域的cookie。虽然这个发送这个请求不是合法用户的本意,但是服务端接收到请求后,通过对比session cookie后会认为这是一个用户本人所发出的请求,于是会按照正常的方式去操作用户的数据。最终导致了用户数据泄露或者被篡改。严重的时候,用户的账户会被攻击者完全控制。

3. 怎么防范CSRF?

同时使用多种方法,即采用双管齐下的方式来防范:

  1. 服务端对于数据操作类的请求,一律实现为post请求。
  2. 使用set-cookie响应头中将sameSite标志位的值置为“strick”。这样子的话,即使当前请求是发往本域的,但是因为它是从第三方域发出的,所以,浏览器是不会为该请求附带上本域的cookie的。
  3. 采用anti-CSRF-token。 具体做法是,除了session cookie(id性质)之外,再加多一个id性质的token来帮助验证请求的合法性。这个token就叫做anti-CSRF-token。anti-CSRF-token的具体值可以直接等于sessionID cookie值(这样的话,服务端就不用存储anti-CSRF-token),也可以由服务端根据一定的算法(md5算法或者hash算法等)从sessiionID中衍生出来(这样的话,服务端需要存储anti-CSRF-token),再把它设置到set-cookie响应头中。客服端在发出请求的时候,那么需要多附上一个token字段,值就是客户端从cookie中拿到的anti-CSRF-token的值。这样子的话,那么服务器就可以通过双重验证(sessionID的值是否合法,anti-CSRF-token与sessionID是否匹配)来准确判断请求的合法性了。

4.关于CSRF的一些误区

  1. post请求能防范CSRF。虽然,post请求比get请求更加安全点,但是我们的应用程序并不能单一地依靠post请求来防范CSRF。攻击者还是可以通过诱导用户点击链接来进行页面跳转,然后在跳转后,属于自己控制的域的页面上伪造post请求表单或者使用ajax来发出post请求。这种情况下,post请求的防范就不起作用了。

  2. 通过对请求头referer或者请求头origin的验证能防范CSRF。其实不然,通过浏览器扩展和重定向的组合,攻击者还是能够自定义http的请求头的,因此还是会存在CSRF漏洞。

  3. 攻击者是无法读取到本域的cookie。这种认识是错误的,当服务端没有将cookie设置为httpOnly,而且页面存在XSS漏洞的情况下,攻击者还是可以获取得到本域的cookie的。

5. 参考资料

  1. CSRF-Wikipedia;

  2. what is CSRF;

  3. Cross-Site Request Forgery Attacks;