Welcome Guest, Not a member yet? Register   Sign In
My CodeIgniter CSRF + Form Helpers
#1

[eluser]Unknown[/eluser]
Hi all,

I've created a CSRF & Form (Extended from CI Form) helpers that aim to tackle the CSRF exploit, and would like to contribute it to anybody who would be interested.

Save the following code into: system/application/helpers/csrf_helper.php
Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* start the session just in case it has not already been started.
* suppress any warning message if it has already been started.
*/
@session_start();  

if (! function_exists('csrf_is_token_valid'))
{
    /**
     * @method bool csrf_is_token_valid() checks if a csrf token is valid
     * @return bool true if token is valid. false if token is invalid.
     */
    function csrf_is_token_valid()
    {
        $result = false;
        if (isset($_POST[csrf_varname()]))
        {
            $result = ((strcmp(csrf_value(), $_POST[csrf_varname()])) == 0);
        }
        return $result;
    }
}  

if (! function_exists('csrf_token'))
{
    /**
     * @method void csrf_token($varlen, $str_to_shuffer) construct a random input field name and assign the token to it.
     * @param int $varlen the length of the input field name that will be generated
     * @param string $str_to_shuffer the string that will be used to generate the input field name
     */
    function csrf_token($varlen = 3, $str_to_shuffer = "abcdefghijklmnopqrstuvwxyz0123456789_")
    {
        $start_pos = mt_rand(0, (strlen($str_to_shuffer) - $varlen));
        $_SESSION["CSRF_NONCE_VARNAME_{$_SERVER["REQUEST_URI"]}"] = substr(str_shuffle($str_to_shuffer), $start_pos, $varlen);
        $_SESSION["CSRF_NONCE_VALUE_{$_SERVER["REQUEST_URI"]}"]    = dohash(microtime() . mt_rand());
    }
}  

if (! function_exists('csrf_varname'))
{
    /**
     * @method string csrf_varname($varlen, $str_to_shuffer) return the generated input field name
     * @param int $varlen the length of the input field name that will be generated
     * @param string $str_to_shuffer the string that will be used to generate the input field name
     * @return string the generated input field name
     */
    function csrf_varname($varlen = 3, $str_to_shuffer = "abcdefghijklmnopqrstuvwxyz0123456789_")
    {
        if (!isset($_SESSION["CSRF_NONCE_VARNAME_{$_SERVER["REQUEST_URI"]}"]))
        {
            csrf_token($varlen, $str_to_shuffer);
        }
        return $_SESSION["CSRF_NONCE_VARNAME_{$_SERVER["REQUEST_URI"]}"];
    }
}  

if (! function_exists('csrf_value'))
{
    /**
     * @method string csrf_value($varlen, $str_to_shuffer) return the token
     * @param int $varlen the length of the input field name that will be generated
     * @param string $str_to_shuffer the string that will be used to generate the input field name
     * @return string the token
     */
    function csrf_value($varlen = 3, $str_to_shuffer = "abcdefghijklmnopqrstuvwxyz0123456789_")
    {
        if (!isset($_SESSION["CSRF_NONCE_VALUE_{$_SERVER["REQUEST_URI"]}"]))
        {
            csrf_token($varlen, $str_to_shuffer);
        }
        return $_SESSION["CSRF_NONCE_VALUE_{$_SERVER["REQUEST_URI"]}"];
    }
}  

if (! function_exists('csrf_clean'))
{
    /*
     * @method void csrf_clean() clears the session variables that store the csrf token
     */
    function csrf_clean()
    {
        session_unregister("CSRF_NONCE_VARNAME_{$_SERVER["REQUEST_URI"]}");
        session_unregister("CSRF_NONCE_VALUE_{$_SERVER["REQUEST_URI"]}");
    }
}  

if (isset($_POST) && count($_POST) > 0 && isset($_SESSION["CSRF_NONCE_VARNAME_{$_SERVER["REQUEST_URI"]}"]))
{
    if (!csrf_is_token_valid()) die("A form re-post or an unknown error has occurred.");
}
?>

Save the following code into: system/application/helpers/MY_form_helper.php
Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
if (! function_exists('form_csrf'))
{
    /*
     * @method string form_csrf($varlen, $str_to_shuffer) returns a constructed hidden input field of the csrf token
     * @param int $varlen the length of the input field name that will be generated
     * @param string $str_to_shuffer the string that will be used to generate the input field name
     * @return string the hidden input field
     */
    function form_csrf($varlen = 3, $str_to_shuffer = "abcdefghijklmnopqrstuvwxyz0123456789_")
    {
        csrf_token($varlen, $str_to_shuffer);
        return form_hidden(csrf_varname(), csrf_value());
    }
}
?>

Edit the file: system/application/config/autoload.php so as to get CI to autoload the necessary helpers.
Code:
/*
| -------------------------------------------------------------------
|  Auto-load Helper Files
| -------------------------------------------------------------------
| Prototype:
|
|    $autoload['helper'] = array('url', 'file');
*/

$autoload['helper'] = array('csrf', 'form', 'security');

To protect your form against CSRF, you just need to add:
Code:
<?=form_csrf();?>
into your form.

Example:
Code:
<form method="post">
<?=form_csrf();?>
<ul>
    <li>name<ul>
        <li>&lt;input name="n" type="text" /&gt;</li>
    </ul>
    </li>
    <li>email<ul>
        <li>&lt;input name="e" type="text" /&gt;</li>
        <li>&lt;input name="s" type="submit" value="submit" /&gt;</li>
    </ul>
    </li>
</ul>
&lt;/form&gt;

and you are done! Whenever the form get submitted, the CSRF Helper will validate the token.

You can find a more complete post of my codes here.


Messages In This Thread
My CodeIgniter CSRF + Form Helpers - by El Forum - 02-11-2008, 10:05 AM
My CodeIgniter CSRF + Form Helpers - by El Forum - 02-28-2008, 10:53 PM
My CodeIgniter CSRF + Form Helpers - by El Forum - 02-21-2010, 03:10 AM
My CodeIgniter CSRF + Form Helpers - by El Forum - 09-27-2010, 11:05 AM
My CodeIgniter CSRF + Form Helpers - by El Forum - 06-12-2012, 10:44 PM
My CodeIgniter CSRF + Form Helpers - by El Forum - 06-12-2012, 11:25 PM
My CodeIgniter CSRF + Form Helpers - by El Forum - 06-13-2012, 02:24 AM



Theme © iAndrew 2016 - Forum software by © MyBB