我正在使用Codeigniter并CSRF通过其config.php文件启用...
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_token_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
Run Code Online (Sandbox Code Playgroud)
然后在我的ajax请求我得到了 cookie name
var cct = $.cookie('csrf_cookie_name');
Run Code Online (Sandbox Code Playgroud)
并在parameters:
csrf_token_name : cct
Run Code Online (Sandbox Code Playgroud)
我的问题:我还需要做其他事吗?
好的,CSRF的最常见情况(或最容易实现)是这样的:
<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=Fred" />
Run Code Online (Sandbox Code Playgroud)
因此,如果您假设您已登录,则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
}
Run Code Online (Sandbox Code Playgroud)
将临时安全令牌添加到这样的URL /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) ...
);
Run Code Online (Sandbox Code Playgroud)
当某些操作需要授权令牌时,您将从数据库加载最后一个或创建新令牌,假设只有当所有可用的令牌都超过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']);
Run Code Online (Sandbox Code Playgroud)
这将如何行动:
如何检查令牌?
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;
}
Run Code Online (Sandbox Code Playgroud)
如果你不想确保动作不会发生两次(例如编辑文章,这适用于删除)只需添加revision_number或类似于你的东西$eventIdentificator).
尝试思考如果会发生什么:
我会使用上面提到的令牌系统,它感觉就像用户舒适/实现复杂性和安全性之间的平衡解决方案,期望与想法和注释的评论:)
防止跨站请求伪造 (CSRF) 攻击的最常见方法是将不可预测的质询令牌附加到每个请求并将它们与用户的会话相关联。
CodeIgniter 中的 CSRF 保护为你做,所以我认为没关系;-)
| 归档时间: |
|
| 查看次数: |
1191 次 |
| 最近记录: |