前言

Web安全一直是老生常谈的一个问题,下面就讲解关于CSRF的内容
关键词:CSRF的由来、CSRF攻击流程、CSRF类型、CSRF特点、CSRF和XSS的区别、CSRF防御手段。

CSRF是什么?

跨站请求伪造(Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。如:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

CSRF攻击流程

综上所述,要想完成一次CSRF攻击,就要进行以下两个步骤:

  1. 登陆受信任的网站A并在本地生成cookie
  2. 在没有登出a的情况下访问了b网站

看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:

  1. 你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。
  2. 你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了……)
  3. 上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。

CSRF类型

GET类型

只需要一个get请求

1
<img src="http://bank.example/withdraw?amount=10000&for=hacker" > 

受害者访问到这个页面的该img的时候就会向该链接发出一次HTTP请求。bankexample就会收到包含受害者登陆信息的一次跨域请求。

POST类型

这种类型的CSRF利用起来通常是一个自动提交的表单例如:

1
2
3
4
5
6
 <form action="http://bank.example/withdraw" method=POST>
<input type="hidden" name="account" value="xiaoming" />
<input type="hidden" name="amount" value="10000" />
<input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script>

访问该页面之后,表单会自动提交,相当于模拟用户完成了一次post操作。

post类型的攻击通常比get要求更严格一点,但是不复杂。任何个人网站,博客,被黑客上传页面的网站都有可能是发起攻击的来源,后端接口不能将安全寄托在仅允许post上面。

链接类型的CSRF

链接类型的CSRF并不常见,比起其他两种用户打开页面就中招的情况下,这种需要用户点击链接才会触发。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常以比较夸张的词语诱骗用户点击eg

1
2
3
<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
重磅消息!!
<a/>

CSRF的特点

  • 攻击发生在第三方网站,而不是被攻击的网站。被攻击的网站无法防止攻击发生。
  • 攻击利用受害在被攻击网站的登陆凭证,冒充受害者提交操作而不是直接窃取数据。
  • 这个过程不能获取登陆凭证而是冒用
  • 跨站请求可用各种方式:图片URL,超链接,CORS,form表单提交等等。部分请求可以直接嵌入在第三方论坛,文章中,难以进行跟踪。

CSRF攻击通常是跨域的,因为外域更容易被攻击者掌控。但是如果本域下有容易被利用的功能,比如可以发图和链接的论坛和评论区,攻击可以直接在本域下面进行,而且这种攻击更加危险。

CSRF和XSS的区别

  • 通常来说CSRF是由XSS实现的,CSRF也时常被称为XSRF
  • 本质上讲,XSS是代码问题,CSRF是HTTP问题。XSS是内容没有过滤导致浏览器将攻击者的输入当代码执行。CSRF则是因为,浏览器在发送请求的时候自动带上了cookie,而一般网站的session都存在cookie里面(token验证可以避免)

防御

  • 验证码:强制用户必须与应用进行交互,才能完成最终请求。此种方式能很好的遏制csrf但用户体验不好。
  • Referer check:请求来源限制,此种方法成本最低,但并不能保证100%有效,因为服务器并不是什么时候都能取到referer,而且低版本的浏览器野村在伪造referer的风险
  • token;token验证的CSRF机制是公认最合适的方案。若网站存在XSS漏洞,这个方法也没有用。