Codeigniter CSRF token problem

11,041

Solution 1

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';

Solution 2

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.

Solution 3

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.

Solution 4

CSRF is valid when token from the hidden field is matching token from the cookie. Check four things:

  1. Don't use native php sessions (session_start etc). Switch to Session class in CI. http://codeigniter.com/user_guide/libraries/sessions.html

  2. Check cookie config in /application/config/config.php

  3. Check value of token in your form, is it different every page refresh?

  4. Maybe try to download current version of CI from https://bitbucket.org/ellislab/codeigniter-reactor/downloads

Solution 5

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);
    }
}
Share:
11,041
Dexty
Author by

Dexty

Updated on June 11, 2022

Comments

  • Dexty
    Dexty almost 2 years

    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');
    
        $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);
    
    }
    
    • hakre
      hakre almost 13 years
      Probably that feature needs cookies and/or javascript. That some who have the error might not have the needed feature enabled, therefore the CSFR check (token based?) does not pass. Which component are you using for the CSFR?
    • Sukumar
      Sukumar almost 13 years
      I used to have the same problem. It used to happen whenever a form that validated is resubmit. May be someone here has a solution.
    • Dexty
      Dexty almost 13 years
      weird, anyone have a solution for this?
  • landons
    landons over 12 years
    Very likely a session issue. I've had nightmare's with CI's session garbage collection process, and I don't know that they've resolved all the issues. Especially if the problem is hard to repeat and isolated to a few people, I'd reduce the session refresh timeout and see if it's easier to reproduce.
  • JonoB
    JonoB over 12 years
    No reason for ajax to cause havoc ericlbarnes.com/post/10728867961/…
  • qwertzman
    qwertzman over 7 years
  • Angga Ari Wijaya
    Angga Ari Wijaya over 7 years
    Agree, regenerate token per request making the form fail when you try resubmit, in case internet timeout or in other situation..., I vote you up..