CSRF protection revisited

November 27, 2008 – 11:11 am Tags: ,

Yesterday, I was talking on IRC with Tom Graham. He was looking for a way to protect GET requests against CSRF. I showed him my CSRF protection plugin, as it would be suitable for protecting GETs too with minor modifications.

This got me thinking what would be the best way to allow you to easily protect certain URLs with it, and here’s the solution…

The dynamic duo

One pattern in Zend Framework apps seems to be that often there is a controller plugin, and an action helper, which exposes the controller plugin’s functionality for easy usage in action controllers.

This is the case here as well:

I’ve modified the CsrfProtect plugin to accomodate the usage in the helper. The helper is completely new, and has methods that you can use in actions to get the CSRF token and check the validity of values in tokens.

Usage

The plugin’s usage is exactly the same as before, so refer to the csrf plugin post for help on that.

Using the action helper is quite simple.

First, we have the initial action and its view:

public function firstAction()
{
    //Assign a token to the view
    $this->view->token = $this->_helper->csrf->getToken();
}
 
//The view:
<a href="secondAction?token=<?= $this->token; ?>">Go to secondAction</a>

And in the second action…

public function secondAction()
{
    //This action is linked from the view in firstAction, and we want to confirm the token:
    $token = $this->getRequest()->getQuery('token');
    if(!$this->_helper->csrf->isValidToken($token))
        throw new Exception('CSRF Token validation failed');
}

Using the helper, you can easily utilize the automatic token generation and all that of the CSRF protection plugin. And it isn’t only limited to GETs either – you could pass the token from the helper to cookies or anything you’d like.

Share this:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • email
  • LinkedIn
  • Pownce
  • Reddit
  • StumbleUpon
  • Technorati

RSS feed Subscribe to my RSS feed

  1. 6 Responses to “CSRF protection revisited”

  2. A while ago i implemented a similar solution to protect actions from csrf that also works for GET requests. I’m sorry it’s in german, but i guess you get the code :>

    http://octavian.supersized.org/archives/17-CSRF-Protection-Updated.html

    By Marc Jakubowski on Nov 27, 2008

  3. Damn it Jani, you stole my blog post. Too quick for me :)

    You implemented it almost exactly the same as me though, bar a few differences in class/method names.

    The one thing I did do differently was to assign a token to the view from a controller plugin as I needed it for every action (when the user was signed in to append to the sign out link).

    Good work!

    By Tom Graham on Nov 27, 2008

  4. Great minds think alike ;)

    By Jani Hartikainen on Nov 27, 2008

  5. Hey I like that.
    You can also use output_add_rewrite_var() to automaticaly add the token as a variable in each page :-)

    By jpauli on Dec 1, 2008

  6. Maybe you should consider adding this method to avoid Token reinit on some action:

    in plugin:
    public function setPreviousToken() {
    $this->_token = $this->_previousToken;
    $this->_session->key = $this->_previousToken;
    }

    in helper:
    public function setPreviousToken()
    {
    return $this->getPlugin()->setPreviousToken();
    }

    if you use an action for image displaying (for exemple), token will be reinitilized so your token will not math anymore.

    use this in your action to avoid this behavior :
    $this->helper->csrf->setPreviousToken();

    By cursed on Feb 13, 2009

  1. 1 Trackback(s)

  2. Jan 22, 2009: How to CSRF protect all your forms | CodeUtopia

Post a Comment