Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
How to Fight CSRF?
  • I just created simple code that shows how to fight against CSRF... with token for each form that is stored and a session. index.php -> Form with hidden field that's a token (also stored in a session),
    process.php -> Check that tokens (from form (that hidden field) and one in a session) are the same,
    bad.html -> Try to CSRF... bad luck. Any easy way to do the same (or the same effect) in Fuel? I see something in config.php, but I don't really get it...
  • Thanks, when 'csrf_expiration' is set to positive number - it works! It was set to '0' and expiration of cookie, weird, but is "until session is destroyed". Still it doesn't work and it should be fixed!
  • Can you create an issue for this at https://github.com/fuel/core/issues?
  • Issue has been added.
  • One problem that I encountered with using Security::check_token() is that it works fine if there are no problems with form submission. However, if the form fails to validate and you use the function repopulate() to make the form sticky, then the form is repopulated with the old csrf_token value. But check_token() automatically regenerates the token, so now the check fails. I ended not using check_token() and instead check it myself with the following:
      $post_token = Input::post('fuel_csrf_token');
      $cookie_token = Input::cookie('fuel_csrf_token');
    
      if ($post_token == $cookie_token)
      {
       return true;
      }
      else
      {
       $this->set_message('check_csrf_token', 'CSRF token error.');
       return false;
      }
     }
    

    If anyone has a better solution, I'd love to hear it.
  • Can you also create a ticket for this?
  • @WanWizard Are you referring to the original issue or the one that I brought up regarding repopulate()?
  • The one you brought up. But you can add it to the original issue as a comment, to keep everything in one place.
  • I just checked, and I don't have that problem in my code. When the view is generated, I add the token input field to the form, with the value of fetch_token(). When the form is submitted, I call check_token(), and it that passes, the form is validated. If that fails, the form is repopulated and displayed. This works without problems. I redirect back to the page after validation, if you continue to load the view after validation, maybe the behaviour is different?
  • I can't seem to find the original issue. Can you provide a link?
  • It's unrelated. It doesn't currently happen in my own code as I add the CSRF field after repopulating. But this shouldn't happen at all, repopulate should ignore the CSRF field. Make a new issue and I'll look into it.
  • I've added it as a new issue.
  • Instead of trying to invent this yourself, why not use the Security class? Fetch a token, and store it in the form. When the form is submitted use check_token() to validate the token. See http://fuelphp.com/docs/classes/security.html
  • Could you explain in a little more detail how you use the csrf token functions? I've tried a few times with no success. If I set csrf_autoload = false, then fetch_token() returns null. If I set csrf_autload = true, then it seems that the token gets reset before I can do the compare and check_token(0 returns false when the form is submitted.
  • Tell me what I do incorrect! I set csrf_autoload to true. I print out token from Security::fetch_token() in form as a hidden field with name - 'token'. I check for that token with Security::check_token( Input::post( 'token' ) ) and it always returns 'false'. Is it alright? I thought it should return 'true', because tokens are the same.
  • I don't use the parameter, as I use the default form field name, but
    <input type="hidden" name="csrf_token" value="<?php echo \\\\Security::fetch_token();?>" />
    
    and
    if ( ! \Security::check_token())
    {
        // handle the error here
    }
    
    works fine in my code.
  • Then it don't work for me... I have...
    'csrf_autoload'   => true,
      'csrf_token_key'  => 'token',
    
    if( !Security::check_token() ) {
    
        exit;
    
       }
    
       // code if all is ok
    

    And all the time 'exit' is executed.
  • Have you tried checking if Input::post('token') and Input::cookie('token') both return a value and match? Otherwise there might be something wrong with either the posted value or the cookie.
  • 1) Thanks again for Debug::dump(), 2) It's kinda problem...
    Variable #1:
    string(32) "c85a869b9fa0167bdf83986aa24b3730"
    
    
    Variable #2:
    string(32) "1804dbb4bae0abe5e59766af4c627cdf"
    

    So... why they aren't equal? What extra-info can I provide you?
  • What's your 'csrf_expiration' (in app/config/config.php)? I've noticed this kind of behaviour with it's set to zero. I assume that should mean 'indefinitely', but in reality it will expire directly. I thought I fixed that? Can you check in your browser if the cookie is set, and if so, what the expiration is? And if you set it to a value, for example 300 (5 minutes), does it then work?

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion