繁体   English   中英

这就是我需要做的就是用php和ajax来防止csrf攻击?

[英]is this all i need to do to prevent csrf attacks with php and ajax?

我正在使用Codeigniter ,我通过其config.php文件启用了CSRF ...

$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_token_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';

然后在我的ajax请求我得到cookie name

var cct = $.cookie('csrf_cookie_name');

parameters

csrf_token_name : cct

我的问题:我还需要做其他事吗?

好的,CSRF的最常见情况 (或最容易实现)是这样的:

<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=Fred" />

因此,如果您假设您已登录bank.example.com那么您的Cookie是“活着的”并将随请求一起发送,因此请求将执行攻击者想要的操作,因此:

Cookie不会保护您免受CSRF的侵害

你能做什么:

尽可能多地通过POST发送请求(无需打扰用户),特别是编辑,创建和删除。 将安全性隐藏到input type='hidden'不是URL中更容易。

检查引用者 (是的,这个小东西阻止你几乎每次来自外部网站的CSRF攻击):

$url = parse_url( isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '');
if( isset( $url['host']) && ($url['host'] == $_SERVER['SERVER_NAME'])){
   // Request have a go
}

将临时安全令牌添加到这样的/article/delete/25/axdefm ...

如果你花了一些时间生成漂亮的URL,你将被发送,因为这只会搞砸它们,这会带来一些问题,例如:

  • 当时的多个动作
  • 对新安全令牌的请求泛滥
  • 让令牌存活多久

您可以为安全令牌创建表,例如:

tokens (
  id INT,
  user_id INT,
  created DATETIME,
  expires DATETIME, -- One of those two should be enough
  value CHAR(30),
  PRIMARY (id),
  FOREIGN KEY (user_id) ...
);

当某些操作需要授权令牌时,您将从数据库加载最后一个或创建新令牌,假设只有当所有可用的令牌都超过15分钟时才会创建新令牌:

function getToken( $userId, $eventIdentificator){
    // Hope this is self explanatory :)
    $db->deleteExpiredTokens();

    // Try to load token newer than 15 minutes
    $row = $db->fetchRow( 'SELECT value FROM tokens WHERE created >= ADD_INTERVAL( NOW(), -15 MINUTES) AND user_id = ?', array( $userId));

    // createToken will return `value` directly
    if( !$row){
        $row = createNewToken( $userId);
    } else {
        $row = $row['value'];
    }

    // Real token will be created as sha1( 'abacd' . 'delete_article_8');
    return sha1( $row . $eventIdentificator);
}

echo 'url?token=' . getToken( $userId, 'delete_article_' . $article['id']);

这将如何行动:

  • 如果您在15分钟内请求相同操作的安全令牌,您将获得相同的令牌
  • 你将获得每个动作的唯一标记
  • 如果您将令牌到期时间设置为4小时,则令牌将在3:45至4:00之间激活
  • 如果攻击者试图在一分钟内向您发送200000个令牌请求,您在数据库中仍然只有一行
  • 每个用户一次最多可以在表中记录16条记录

如何检查令牌?

function checkToken( $userId, $eventIdentificator, $token){
    $db->deleteExpiredTokens();

    // Just find matching token with brute force
    $rs = $db->fetch_rowset( 'SELECT value FROM tokens WHERE created >= ADD_INTERVAL( NOW(), -15 MINUTES) AND user_id = ?', array( $userId));
    while( $row = $rs->fetch_row){
       if( $token == sha1( $row['value'] . $eventIdentificator)){
           return true;
       }
    }
    return false;
}

如果你不确定动作不会发生两次(例如编辑文章,这适用于删除)只需添加revision_number或类似于你的$eventIdentificator )。

尝试思考如果会发生什么:

  • 攻击者请求许多令牌
  • 用户将写几个小时的文章
  • 如果你有一个包含数百篇文章删除按钮的表格

我会使用上面提到的令牌系统,它感觉就像用户舒适/实现复杂性和安全性之间的平衡解决方案,期望与想法和注释的评论:)

防止跨站请求伪造(CSRF)攻击的最常用方法是向每个请求附加不可预测的质询令牌,并将它们与用户的会话相关联。

CodeIgniter中的CSRF保护为你做,所以我认为没关系;-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM