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.generate a unique value for CSRF token in _csrf_set_hash() function:
$this->csrf_hash = md5(uniqid(rand(), TRUE));
2.Insert that token into form hidden field (using form_open helper)
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.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;
}
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.