开发者

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:

  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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜