Codeigniter CSRF token problem
I've made a simple signup/newsletter site, but I've got a weird problem. Some people get a error that says
An Error Was Encountered The action you have requested is not allowed.
I've already tried google and found that people had the same problem when CSRF was set to true. However, i doesn't happens to everyone, just a small group of people. I'm using form_open and form_close and i can see the hidden field (token).
I'm using the latest version of Codeigniter 2.0.2
This is my controller
function __construct() {
parent::__construct();
session_start();
}
function index() {
$this->load->model('beta_signup_model');
开发者_StackOverflow社区
$this->form_validation->set_rules('mail','e-mail','required|valid_email|xss_clean|callback__mail_check');
// Check for errors
if($this->form_validation->run() == FALSE) {
// The system found a form validation error
} else {
// No errors found
$_SESSION['mail_success'] = 1;
$_SESSION['mail'] = $this->input->post('mail');
redirect(base_url() . 'confirm');
}
///// FILLS OUT INPUT FIELDS /////
// Loads field_populator_helper
$this->load->helper('field_populator_helper');
// Defines input field names
$input_names = array(
'mail',
);
// Defines default values
$default_values = array(
'Skriv inn e-posten din..',
);
// Auto-populates fields with blur and focus
$data['field_populator'] = populateFields($input_names, $default_values);
$this->load->view('frontpage_view', $data);
}
It may help to change your 'sess_cookie_name' in config.php to ensure that it has no spaces or underscores.
$config['sess_cookie_name'] = 'mycookiename';
I had the same problem: totally clean instal of CI 2.1.0, on MAMP, and just following along the tutorial in the User Guide.
After a lot of searching and googling, I found that in 'application/config.php', the variable $config['cookie_prefix'] must always be set to empty, otherwise if CSRF protection is turned on, this error will occur.
It could be that there are other issues involved - ie., session library, encryption or XSS protection, etc. - but just leaving the 'cookie_prefix' empty seems to have sorted it for me.
I hope this helps others.
CSRF is valid when token from the hidden field is matching token from the cookie. Check four things:
Don't use native php sessions (session_start etc). Switch to Session class in CI. http://codeigniter.com/user_guide/libraries/sessions.html
Check cookie config in /application/config/config.php
Check value of token in your form, is it different every page refresh?
Maybe try to download current version of CI from https://bitbucket.org/ellislab/codeigniter-reactor/downloads
I use my own csrf helper, because I have found that when setting the option in the config to true it plays havoc with my ajax calls.
I use *xsrf_get_token_field()* for generating the field and *xsrf_check_token()* as a custom callback in my form validation.
<
?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('xsrf_get_token')) {
/**
* Get XSRF Token
*
* Returns a token that exists for one request that verifies that
* the action was executed by the person that requested it
*
* @return string
*/
function xsrf_get_token() {
$ci =& get_instance();
if ($ci->session->userdata('xsrf_hash')) {
$token = $ci->session->userdata('xsrf_hash');
} else {
// Generate the token
$token = sha1(microtime().$ci->uri->uri_string());
// Set it in the session
$ci->session->set_userdata('xsrf_hash', $token);
}
//Return it
return $token;
}
}
if ( ! function_exists('xsrf_get_token_field')) {
/**
* Get XSRF Token Field
*
* Returns an xhtml form element to include xsrf token.
* You can specify the id/name attribute of the input.
* Has a dependancy to get_xsrf_token().
*
* @param string The id/name to be used
* @return string
*/
function xsrf_get_token_field($name='auth_token') {
return '<input type="hidden" id="'.$name.'" name="'.$name.'" value="' .xsrf_get_token(). '" />';
}
}
if ( ! function_exists('xsrf_delete_token')) {
/**
* Delete XSRF Token
*
* Deletes the xsrf token
*
* @return boolean
*/
function xsrf_delete_token() {
$ci =& get_instance();
if ($ci->session->userdata('xsrf_hash')) {
$ci->session->unset_userdata('xsrf_hash');
return TRUE;
} else {
return FALSE;
}
}
}
if ( ! function_exists('xsrf_check_token')) {
/**
* Get XSRF Token Field
*
* Checks that the token is still valid, returns true if so.
* Deletes old token after valid or fail.
* Has a dependacy to xsrf_delete_token()
*
* @param string The challenge token
* @return boolean
*/
function xsrf_check_token($challenge_token) {
// CI
$ci =& get_instance();
// Get the stored token
$token = $ci->session->userdata('xsrf_hash');
// Delete the old token
xsrf_delete_token();
// Returns if the token is the right token
return ($token == $challenge_token);
}
}
You need to update core security files or just take csrf code from current version of codeigniter codeigniter core secuirty file .
You can use ajax as :
var cct = $("input[name=csrf_test_name]").val(); $.post(site_url + "user/update_product", { product_id: id , 'csrf_test_name': cct})
Codeigniter CSRF is not regenerating token on page refresh. It ll regenrate only on post not on get. Security testers found it as a vulnerability. If any person got solution for this .. please share that, it ll be helpfull for everyone.
For anyone using Codeigniter 3.0, you can do the following:
Change
$config['csrf_regenerate'] = TRUE;
to
$config['csrf_regenerate'] = FALSE;
This stops CSRF tokens being regenerated on each submission.
精彩评论