问题描述
为什么生成的CSRF保护令牌不会通过SESSION保存和使用,例如建议?目前在CI2中,CSRF保护机制(在安全类中)是:
Why generated CSRF protection token is not saved and used via SESSION like suggested here? Currently in CI2, the CSRF protection mechanism (in Security class) is such:
1.在_csrf_set_hash()函数中生成CSRF令牌的唯一值:
1.generate a unique value for CSRF token in _csrf_set_hash() function:
$this->csrf_hash = md5(uniqid(rand(), TRUE));
2.将此令牌插入到隐藏字段中(使用form_open帮助程序)
2.Insert that token into form hidden field (using form_open helper)
3.用户提交表单,服务器通过POST获取令牌。 CI在Input类中的_sanitize_globals()函数中执行令牌验证:
3.A user submits the form and a server gets the token via POST. The CI performs token verification in "_sanitize_globals()" function in Input class:
$this->security->csrf_verify();
4. Security类的函数csrf_verify只是检查POST ['token'] set,是POST ['token']等于COOKIE ['token'];
4.The function "csrf_verify" of Security class just checks is POST['token'] set and is POST['token'] equal to COOKIE['token'];
public function csrf_verify(){
// If no POST data exists we will set the CSRF cookie
if (count($_POST) == 0)
{
return $this->csrf_set_cookie();
}
// Do the tokens exist in both the _POST and _COOKIE arrays?
if ( ! isset($_POST[$this->_csrf_token_name]) OR
! isset($_COOKIE[$this->_csrf_cookie_name]))
{
$this->csrf_show_error();
}
// Do the tokens match?
if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name])
{
$this->csrf_show_error();
}
// We kill this since we're done and we don't want to
// polute the _POST array
unset($_POST[$this->_csrf_token_name]);
// Nothing should last forever
unset($_COOKIE[$this->_csrf_cookie_name]);
$this->_csrf_set_hash();
$this->csrf_set_cookie();
log_message('debug', "CSRF token verified ");
return $this;
}
为什么不在会话中存储令牌? IMHO只是检查是否为POST ['token']非空且等于COOKIE ['token']是不够的,因为两者都可能由邪恶网站发送。
Why not to store token in session? IMHO just checking is POST['token'] non-empty and is equal to COOKIE['token'] is not sufficient because both might be sent by an evil site.
推荐答案
在CodeIgniter中,他们不在代码中的任何地方使用本地PHP会话。
In CodeIgniter, they don't use native PHP sessions anywhere in the code.
PHP会话。
使用CodeIgniter Session类时,有以下两种方式之一:通过Cookie存储数据,或将它们存储在数据库中。 [reference:]
While using CodeIgniter Session class, there's either: store data via cookies, or store them in database. [ reference: http://codeigniter.com/user_guide/libraries/sessions.html ]
检查csrf数据时,每次检查数据库都没有意义,将它们存储在cookie中是合理的。
While checking for csrf data, it wouldn't make sense to check the database every time, it would be plausible to store them in the cookies.
我认为这通常是安全的,但是这个方法有一些漏洞。也许用服务器端密钥加密它可能有助于增加安全性...
I think it's generally safe, but there are some windows of vulnerability with this method. Perhaps encrypting it with server side key might help increase the security...
EDIT:
根据文章,它说,CSRF保护与会话无关的现时(由CodeIgniter使用)有漏洞CSRF + MITM攻击():
According to the article, it says that CSRF Protection with Session independent nonce (used by CodeIgniter) has a vulnerability to CSRF + MITM Attack (Man-in-the-Middle):
攻击者可以使用Set-Cookie设置CSRF cookie,然后在POST表单数据中提供
a匹配令牌。由于网站没有将
的会话cookie绑定到CSRF cookie,它没有办法确定
的CSRF令牌+ cookie是真的(做散列等
之一他们将不工作,因为攻击者可以直接从
站点获得有效的配对,并在攻击中使用该配对。)
很多,函数 csrf_verify()仅检查cookie和输入POST是否为
相等,这两者都可以通过简单的javascript创建。
Pretty much, the function csrf_verify() only checks whether the cookie and input POST is equal, which both can be created through simple javascript. You should think twice about using this if you are serious about security.
资料来源:
这篇关于为什么codeigniter2不以更安全的方式存储csrf_hash,例如session?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!