大家好,又见面了,我是你们的朋友全栈君。
CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,一般是攻击者冒充用户进行站内操作,它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则是伪装成受信任用户的请求来访问操作受信任的网站。
CSRF攻击经常利用目标站点的身份验证机制,CSRF攻击这一弱点的根源在于Web的身份验证机制虽然可以向目标站点保证一个请求来自于经过站点认证的某个用户的账号,但是却无法保证该请求的确是那个用户发出的或者是经过那个用户批准的。 目前web网站泛用的身份验证机制就是cookie-session认证机制,来跟踪记录用户的行为。 CSRF攻击依赖下面的假定: 攻击者了解受害者所在的站点; 攻击者的目标站点具有持久化授权cookie或者受害者具有当前会话cookie; 目标站点没有对用户在网站行为的第二授权; 欺骗用户的浏览器发送HTTP请求给目标站点(也就是忽悠用户点击攻击链接)或者攻击者控制部分or全部站点(比如攻击者通过XSS拿到未失效且经过网站授权的cookie)。 参考深入解析跨站请求伪造漏洞:原理剖析。 比如攻击者编写了一个在用户的银行站点上进行取款的form提交的链接,并将此链接作为图片src。如果用户的银行在cookie中保存他的授权信息,并且此cookie没有过期,那么当用户的浏览器尝试装载图片时将提交这个取款form和他的cookie,这样在没经用户同意的情况下便授权了这次转账。 如下图所示:
常见威胁
1:通过邮件、图片链接骗取用户,如下html所示
<p>创建图片链接:
<a href="http://www.w3cschool.cn/Pj/Index/getList?id=1">
<img src="http://www.baidu.com/link?url=16pic_1596549_b.jpg" alt="HTML 教程" width="32" height="32"></a></p>
含有CSRF攻击的图片,这种一般是get方式,有时需要提交表单,采用POST方式提交。此时构造个隐藏的HTML表单提交些数据过去就可以了。参考csrf的post攻击。
2:多窗口浏览器就帮了一点忙。 多窗口浏览器(firefox、遨游、MyIE……)便捷的同时也带来了一些问题,因为多窗口浏览器新开的窗口是具有当前所有会话的。单窗口浏览器IE就不会,如我用ie登陆了我的Blog,然后我想看新闻了,又运行一个IE进程,这个时候两个IE窗口的会话是彼此独立的,从看新闻的IE发送请求到Blog不会有我登录的cookie;但是多窗口浏览器永远都只有一个进程,各窗口的会话是通用的,即看新闻的窗口发请求到Blog是会带上我在blog登录的cookie。
转载自csrf危害 案例一:
一个银行站点存在一个csrf漏洞,用户A转账给B用户2000元,执行转账操作后会对银行发送一次请求:“http://www.bank.com/money?user=A&num=2000&transfer=B”,然后A用户就会把自己的2000元转到B的账户下。在发送这个请求给银行服务器时,服务器首先会验证这个请求是否为一个合法的session,并且用户A确认登陆才可以验证通过。
如果此时有一个恶意用户C想把A用户的钱转到自己的账户下,那么他可以构造 http://www.bank.com/money?user=A&num=2000&transfer=C 这个请求,但是这个请求必须有A用户发出才可以生效,此时恶意用户C可以搭建一个自己的网站,在网站中写入如下代码 <img src=“http://www.bank.com/money?user=A&num=2000&transfer=C”>,之后诱导A用户访问自己的网站,当A访问这个网站时,这个网站就会把img标签里的URL发给银行服务器,而此时除了这个请求以外,还会把A用户的cookie一起发到服务器,如果此时A用户的浏览器与银行的session没有过期,那么就会在A用户毫不知情的情况下执行转账给C的操作。
案例二:
一个cms系统的管理后台,可以发送一个post请求添加一个管理员,url为”http://www.cms.com/add“, 由于没有加token或者验证码限制,恶意攻击者可以在自己的服务器evil.com上建立一个a.html的文件,a.html文件是一个添加管理员账户的表单,上面写入需要添加的账户用户名及密码,当网站管理员打开”evil.com/a.html“的时候,并且管理员的session没有失效,那么此时a.html就会请求受攻击网站,在管理员毫不知情的情况下添加一个后台账户。 a.html内容如下:
<form method="post" action="http://www.cms.com/add" enctype="application/x-www-form-urlencoded">
<label>账号:</label><input type="hidden" name="name" value="123456"/>
<label>密码:</label><input type="hidden" name="pwd" value="123456"/>
</form>
对于web站点,将持久化的授权方法(例如cookie或者HTTP授权)切换为瞬时的授权方法(在每个form中提供隐藏field,如token),这将帮助网站防止这些攻击。 服务端的CSRF方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数。
//表单
<!DOCTYPE HTML>
<html>
<body>
<form method="post" action="Home/index/form" enctype="application/x-www-form-urlencoded">
<label>账号:</label><input name="name" value=""/>
<label>密码:</label><input name="pwd" value=""/>
<button>提交</button>
</form>
</body>
</html>
//生成token代码省略
;;;;;
// 自动表单令牌验证
public function autoCheckToken($data)
{
// 支持使用token(false) 关闭令牌验证
if (isset($this->options['token']) && !$this->options['token']) {
return true;
}
if (C('TOKEN_ON')) {
$name = C('TOKEN_NAME', null, '__hash__');
if (!isset($data[$name]) || !isset($_SESSION[$name])) {
// 令牌数据无效
$this->error='令牌数据无效';
return false;
}
// 令牌验证
list($key, $value) = explode('_', $data[$name]);
if (isset($_SESSION[$name][$key]) && $value && $_SESSION[$name][$key] === $value) {
// 防止重复提交
unset($_SESSION[$name][$key]); // 验证完成销毁session
return true;
}
// 开启TOKEN重置
if (C('TOKEN_RESET')) {
unset($_SESSION[$name][$key]);
}
$this->error='表单重复提交';
return false;
}
return true;
}
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/144317.html原文链接:https://javaforall.cn