浅谈CSRF攻击方式,原理,防范

本文深入解析了跨站请求伪造(CSRF)攻击的概念、危害及防御策略。CSRF利用网站对用户浏览器的信任,使攻击者能以用户名义执行恶意操作,如发送邮件、盗取账号等,严重威胁个人隐私和财产安全。文章详细介绍了CSRF的攻击流程,并提供了服务端防御方法,如Cookie Hashing和One-Time Tokens,帮助开发者有效抵御此类攻击。

一.CSRF是什么?

跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

二.CSRF可以做什么?

你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账,造成的问题包括:个人隐私泄露以及财产安全。

三.CSRF的原理

一个典型的CSRF攻击有着如下的流程:

*受害者登录a.com,并保留了登录凭证(Cookie)。
*攻击者引诱受害者访问了b.com。
*b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会默认携带a.com的Cookie。
*a.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。
*a.com以受害者的名义执行了act=xx。
*攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a.com执行了自己定义的操作。

四.CSRF攻击防御策略

CSRF的防御可以从服务端和客户端两方面着手

4.1服务端进行CSRF防御

服务端的CSRF方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数。
(1).Cookie Hashing(所有表单都包含同一个伪随机值):
这可能是最简单的解决方案了,因为攻击者不能获得第三方的Cookie(理论上),所以表单中的数据也就构造失败了:>

<?php
    //构造加密的Cookie信息
    $value = “DefenseSCRF”;
    setcookie(”cookie”, $value, time()+3600);
  ?>

在表单里增加Hash值,以认证这确实是用户发送的请求。

<?php
  $hash = md5($_COOKIE['cookie']);
?>
<form method=”POST” action=”transfer.php”>
  <input type=”text” name=”toBankId”>
  <input type=”text” name=”money”>
  <input type=”hidden” name=”hash” value=”<?=$hash;?>”>
  <input type=”submit” name=”submit” value=”Submit”>
</form>

然后在服务器端进行Hash值验证

<?php
        if(isset($_POST['check'])) {
             $hash = md5($_COOKIE['cookie']);
             if($_POST['check'] == $hash) {
                  doJob();
             } else {
        //...
             }
        } else {
      //...
        }
     ?>
(2). One-Time Tokens(一次性令牌)

在实现One-Time Tokens时,需要注意一点:就是“并行会话的兼容”。如果用户在一个站点上同时打开了两个不同的表单,CSRF保护措施不应该影响到他对任何表单的提交。考虑一下如果每次表单被装入时站点生成一个伪随机值来覆盖以前的伪随机值将会发生什么情况:用户只能成功地提交他最后打开的表单,因为所有其他的表单都含有非法的伪随机值。必须小心操作以确保CSRF保护措施不会影响选项卡式的浏览或者利用多个浏览器窗口浏览一个站点。

//设置token
public function set_token(){
    $token  = random(40);
    $_SESSION['csrf_token'] = $token;
}
//生产token
 function random($length = 16)
{
            $bytes = openssl_random_pseudo_bytes($length * 2);
    if ($bytes === false)
    {
        return false;
    }
    return substr(str_replace(array('/', '+', '='), '', base64_encode($bytes)), 0, $length);
}

//WEB表单生成隐藏输入域的函数
function function_csrf_field($params, &$smarty){
    $token = get_token();
    return '<input type="hidden" name="_token" value="'.$token.'">';
}

//WEB表单结构
<?php
       session_start();
       include(”functions.php”);
  ?>
  <form method=”POST” action=”transfer.php”>
       <input type=”text” name=”toBankId”>
       <input type=”text” name=”money”>
       <? function_csrf_field(); ?>
       <input type=”submit” name=”submit” value=”Submit”>
  </FORM>
  
//服务端核对令牌
//获取token可以进行验证
public function get_token(){
    return $_SESSION['csrf_token'];
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值