[英]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是“活着的”并将随请求一起发送,因此请求将执行攻击者想要的操作,因此:
你能做什么:
尽可能多地通过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']);
这将如何行动:
如何检查令牌?
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.