9

I'm actually playing around with Laravel 4. Right now I'm implemented the CSRF token security on form post.

The problem is that, this is not actually working in the sense that the token generated in the session Session::token() is always the same so when I try to re-submit a form or even post a form from another server, the security check is not working Session::token() != Input::get('_token') (filters.php)

Anyone already faced this issue?

EDIT :
Ok I found the explanation of this. The token is actually different for each machine/session. It makes more sense now :) Thanks to everyone for your help

lkartono
  • 2,323
  • 4
  • 29
  • 47

4 Answers4

9

when the form is submitted, after processing the form you should change the CSRF token like Session::put('_token', md5(microtime())); this will protect from form re-submission.. for more info you can see this and this

Community
  • 1
  • 1
Trying Tobemyself
  • 3,668
  • 3
  • 28
  • 43
  • 1
    Thank you for your answer. Indeed, so far this is the only way who works but I think this is really dumb to give to developers a csrf-token security check out of the box if we still need to care about those kind of details. This should work out of the box :( Thanks again – lkartono Aug 23 '13 at 15:17
  • Wow. I just tested that and got the same token multiple times. You have to wonder what they think the point of a CSRF token is.... I wonder if it's fixed in 5. – DanielM May 01 '15 at 13:12
3

I use the built-in regenerateToken function this way in my app/filter.php:

Route::filter('csrf', function()
{
    if (Session::token() != Input::get('_token'))
    {
        Session::regenerateToken();
        return *Redirect / Exception*
    }
    Session::regenerateToken();
});

Another note when you redirect with input!

In laravel 4 the token is generated when you are using {{ Form::open(...) }} this way:

public function token()
{
    return $this->hidden('_token', $this->csrfToken);
}

So it uses a hidden input, which will set its value from Input::old function if it exists.

To prevent this you'll need to use Input::except('_token') if you wouldn't like to make a form with an already outdated token like this:

return Redirect::route('routename')->withInput(Input::except('_token'));
user2042930
  • 640
  • 1
  • 7
  • 14
2

Inside the form you have to create the token like this:

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

After that the token will be sent with the input. So when you receive the input you have to check the token like this:

Route::post('register', array('before' => 'csrf', function()
{
    return 'You gave a valid CSRF token!';
}));

This way you will place a filter before the route is accessed that checks the CSRF token.

Got this from the Laravel documentation right here

Rubens Mariuzzo
  • 28,358
  • 27
  • 121
  • 148
Dries Marien
  • 211
  • 2
  • 9
  • 1
    Thank you for your answer. I did all of this but my issue is about the token itself which is not updated. Even if I refresh the page, the token is still the same so the filter will always return true. – lkartono Aug 23 '13 at 07:18
0

When you use Blade to create the form, the _token gets automatically rendered inside of the form

<?php echo Form::open(array('url' => '/', 'files' => true, 'id' => 'shareForm', 'method' => 'post')) ?>
...
HTML
...
 <?php echo Form::close() ?>
Eduardo Chongkan
  • 752
  • 7
  • 12