Codeigniter CSRF令牌问题

时间:2011-07-05 10:51:55

标签: php codeigniter frameworks token

我已经制作了一个简单的注册/通讯网站,但我遇到了一个奇怪的问题。有些人会收到错误消息

  

遇到错误行动   你提出要求是不允许的。

我已经尝试过google,发现当CSRF设置为true时,人们遇到了同样的问题。但是,我并不是每个人,只是一小群人。我正在使用form_open和form_close,我可以看到隐藏字段(令牌)。

我正在使用最新版本的Codeigniter 2.0.2

这是我的控制器

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

}

6 个答案:

答案 0 :(得分:2)

在config.php中更改'sess_cookie_name'可能会有所帮助,以确保它没有空格或下划线。

$config['sess_cookie_name'] = 'mycookiename';

答案 1 :(得分:2)

我遇到了同样的问题:在MAMP上完全干净安装CI 2.1.0,并按照用户指南中的教程进行操作。

经过大量搜索和谷歌搜索后,我发现在&app; / config.php'中,变量$ config [' cookie_prefix']必须始终设置为空,否则如果启用CSRF保护,则会发生此错误。

可能涉及其他问题 - 即会话库,加密或XSS保护等 - 但只是离开了' cookie_prefix'空似乎已经为我排序了。

我希望这有助于其他人。

答案 2 :(得分:1)

当隐藏字段中的令牌与Cookie中的令牌匹配时,CSRF有效。检查四件事:

  1. 不要使用本机php会话(session_start等)。切换到CI中的Session类。 http://codeigniter.com/user_guide/libraries/sessions.html

  2. 检查/application/config/config.php

  3. 中的cookie配置
  4. 检查表单中令牌的值,每次刷新页面都不一样吗?

  5. 也许尝试从https://bitbucket.org/ellislab/codeigniter-reactor/downloads

  6. 下载当前版本的CI

答案 3 :(得分:1)

我使用自己的csrf助手,因为我发现在将config中的选项设置为true时会对我的ajax调用造成严重破坏。

我使用* xsrf_get_token_field()*生成字段,并使用* xsrf_check_token()*作为表单验证中的自定义回调。

<

?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);
    }
}

答案 4 :(得分:1)

  • 您需要更新核心安全文件或从当前版本的codeigniter codeigniter core secuirty file 获取csrf代码。

  • 您可以将ajax用作: var cct = $("input[name=csrf_test_name]").val(); $.post(site_url + "user/update_product", { product_id: id , 'csrf_test_name': cct})

  • Codeigniter CSRF不会在页面刷新时重新生成令牌。它只会在帖子上重新生成而不是获取。安全测试人员将其视为漏洞。 如果有人为此获得解决方案..请分享一下,这对每个人都有帮助。

答案 5 :(得分:1)

对于使用Codeigniter 3.0的任何人,您可以执行以下操作:

更改

$config['csrf_regenerate'] = TRUE;

$config['csrf_regenerate'] = FALSE;

这会停止在每次提交时重新生成CSRF令牌。