One token vs. multiple tokens to prevent CSRF attacks

我的未来我决定 提交于 2019-12-03 15:05:22

To solve this problem, you could create a token string with a unique key and store the pairs of keys/tokens in the session (as userdata in CodeIgniter).

Considering this scenario, You'll need these steps:

  1. Creating a unique token key.
  2. Creating a token string.
  3. Storing the key/token pair in the session (userdata).
  4. Creating 2 hidden <input> elements for CSRF key and token.
  5. Validating the posted key/token by checking the existence of key/token in the session.

Getting to work:

$csrf_key   = "TOKEN_" . mt_rand(0, mt_getrandmax());
$csrf_token = hash("sha512", mt_rand(0, mt_getrandmax()));
// Store the key/token pair in session
$this->session->set_userdata($csrf_key, $csrf_token);

Adding hidden inputs:

<form action="path/to/handler/page" method="post">
    <!-- form input elements -->
    <input type="hidden" name="csrf_key" value="<?php echo $csrf_key; ?>">
    <input type="hidden" name="csrf_token" value="<?php echo $this->session->userdata($csrf_key); ?>">
</form>

Validating the posted key/token:

if (count($_POST)) {
    if (! isset($_POST['csrf_key']) or ! isset($_POST['csrf_token'])) {
        die('No CSRF token found, invalid request.');     
    }

    $key   = $this->input->post('csrf_key');
    $token = $this->input->post('csrf_token');

    if ($token !== $this->session->userdata($key)) {                
        die('Invalid CSRF token, access denied.');
    }
}

I scanned your post and don't see a reason why not to use the base codeigniter CSRF protection? It seems you are reinventing the wheel and creating problems that don't exist within its standard implementation.

Not to mention you are violating DRY principles by trying to print your tokens to every form. Any reason why not to keep it simple?

Codeigniter has build in CSRF protection that can be enabled in /application/config/config.php

$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_token_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!