上篇文章总结了遇到过的一个XSS漏洞问题,这次顺便写写自己了解的CSRF。
一、简介
CSRF是Cross-site request forgery的缩写,中文的世界一般说法是跨站请求伪造。简单地说,就是黑客伪造了一个目标网站的地址,欺骗用户去点击用浏览器打开这个地址,如果用户登陆了这个网站,就可以绕过后台用户身份验证,执行一些操作。
伪造的请求地址可以包装成图片、超链接、HTML文本等,通常通过评论、留言放在第三方网站(也可以放在目标网站中)或邮件主体内容中,诱导用户点击。利用用户登陆目标网站,Cookie有效,冒充用户真实身份,执行发邮件、发消息、购物、转账等操作。
二、案例
一个真实的案例
今天收到安全部门的邮件,说tv.weibo.com域下某活动,后端未验证referer、origin等字段,存在CSRF可通过诱导用户点击链接来发微博。访问链接[https://tv.weibo.com/seat?event_id=628&action=create]即可。
修复建议:
1、推荐后端严格校验referer、origin等;或者加全局token,每次请求带上token。校验referer时最好不要使用正则匹配的形式,假如PHP的话,可以使用parse_url函数来提取referer中的host来进行判断。
2、排查其他接口是否存在类似问题。
大概意思就是攻击者可以把上面的链接放在其他站点,诱导用户去点击,由于这个地址的后端没有安全校验,用户点击这个链接后,假如用户微博是在线登录态,就可以利用用户信息发微博。
例如:把地址伪装在dd” rel=”noopener” target=”_blank”>这个点击下。【修复之前是可以正常访问的,现在被限制了】
最简单的增加referer校验即可
private function checkReferer() { $request = $this->getRequest(); $referer = $request->getServer('HTTP_REFERER'); if ($referer) { $url_info = @parse_url($referer); $allow_referer = [$_SERVER['HTTP_HOST'], $_SERVER['SERVER_NAME'], 'weibo.com', 'weibo.cn', 's.weibo.com']; Helper_Log::writeApplog('referer', sprintf('referer: %s|url_info: %s|allow_referer: %s', $referer, json_encode($url_info), json_encode($allow_referer))); if (!in_array($url_info['host'], $allow_referer)) { echo '抱歉,你没有权限访问此页面'; exit; } } else { Helper_Log::writeApplog('no_referer', sprintf('server info: %s', json_encode($_SERVER))); } }
理论上任何请求都会有referer, 测试发现有些请求没有referer。还需要进一步观察。
没有referer的情况
0、非浏览器请求,爬虫等 1、协议不一致。https的站点,链接是http的
三、类型
图片类型:
超链接类型:
惊爆!范冰冰艳照真流出了!!!
HTML文本:
<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>
例如:Google Gmail 2007年CSRF漏洞。
四、防御
常用防御方式:
0、校验请求Referer。 1、token校验。 2、Origin校验。Access-Control-Allow-Origin