你了解可怕的CSRF攻击吗?
来源丨小怪聊职场
www.jianshu.com/p/67408d73c66d
什么是CSRF攻击
CSRF攻击的全称是跨站请求伪造( cross site request forgery),是一种对网站的恶意利用。CSRF 是通过伪装来自受信任用户的请求来利用受信任的网站。你可以这么理解 CSRF攻击:攻击者盗用了你的身份,以你的名义向第三方网站发送恶意请求。CRSF能做的事情包括:利用你的身份发邮件、发短信、进行交易转账等,甚至盗取你的账号。
CSRF攻击原理
首先用户
C浏览并登录了受信任站点A;登录信息验证通过以后,站点
A会在返回给浏览器的信息中带上已登录的cookie,cookie信息会在浏览器端保存一定时间(根据服务端设置而定);完成这一步以后,用户在没有登出(清除站点
A的cookie)站点A的情况下,访问恶意站点B;这时恶意站点
B的某个页面向站点A发起请求,而这个请求会带上浏览器端所保存的站点A的cookie;站点
A根据请求所带的cookie,判断此请求为用户C所发送的。
因此,站点 A会根据用户 C的权限来处理恶意站点 B所发起的请求,而这个请求可能以用户 C的身份发送 邮件、短信、消息,以及进行转账支付等操作,这样恶意站点 B就达到了伪造用户 C请求站点 A的目的。
受害者只需要做下面两件事情,攻击者就能够完成 CSRF攻击:
登录受信任站点
A,并在本地生成cookie;在不登出站点
A(清除站点A的cookie)的情况下,访问恶意站点B。
很多情况下所谓的恶意站点,很有可能是一个存在其他漏洞的受信任且被很多人访问的站点,这样,普通用户可能在不知不觉中便成为了受害者。
CSRF攻击举例
当你登录网站 A后,没有及时登出,这时你访问了论坛 B,不幸的事情发生了,你会发现你的账号里面少了 10000块...
当然,绝大多数网站都不会使用 GET请求来进行数据更新,因此,攻击者也需要改变思路,与时俱进。
假设银行将其转账方式改成 POST提交,而论坛 B恰好又存在一个 XSS漏洞,恶意用户在它的页面上植入如下代码:
<form id="aaa" action="http://www.xxx.com/transfer.do" metdod="POST" display="none">
<input type="text" name="accountNum" value="10001"/>
<input type="text" name="money" value="10000"/>
</form>
<script>
var form = document.forms('aaa');
form.submit();
</script>
当然,以上只是举例,正常来说银行的交易付款会有USB key、验证码、登录密码和支付密码等一系列屏障,流程比上述流程复杂得多,因此安全系数也高得多!
CSRF的防御
尽量使用POST,限制GET
GET接口太容易被拿来做 CSRF攻击,看上面示例就知道,只要构造一个 img标签,而 img标签又是不能过滤的数据。接口最好限制为 POST使用, GET则无效,降低攻击风险。
当然 POST并不是万无一失,攻击者只要构造一个 form就可以,但需要在第三方页面做,这样就增加暴露的可能性。
将 cookie设置为 HttpOnly
CRSF攻击很大程度上是利用了浏览器的 cookie,为了防止站内的 XSS漏洞盗取 cookie,需要在 cookie中设置 “HttpOnly”属性,这样通过程序(如 JavaScript脚本、 Applet等)就无法读取到 cookie信息,避免了攻击者伪造 cookie的情况出现。
在 Java的 Servlet的API中设置 cookie为 HttpOnly的代码为:response.setHeader("Set-Cookie","cookiename=cookievalue;HttpOnly");
增加Token
CSRF攻击之所以能够成功,是因为攻击者可以伪造用户的请求,该请求中所有的用户验证信息都存在于 cookie中,因此攻击者可以在不知道用户验证信息的情况下直接利用用户的 cookie来通过安全验证。由此可知,抵御 CSRF攻击的关键在于:在请求中放入攻击者所不能伪造的信息,并且该信总不存在于 cookie之中。鉴于此,系统开发人员可以在 HTTP请求中以参数的形式加入一个随机产生的 token,并在服务端进行 token校验,如果请求中没有 token或者 token内容不正确,则认为是 CSRF攻击而拒绝该请求。
通过Referer识别
参考文献
-
《大型分布式网站架构设计与实践》
