CSRF protection on POST, PATCH, PUT and DELETE request in Laravel

August 14, 2014

While Laravel does come with a great facility for CSRF protection out of the box, it does actually need to be configured. By default, the Form::open() helper is going to drop the _token into your form to pass it along with the request so all you need to do is ensure that is it checked on the other side. Normally, you're going to want to check this on any request that is not idempotent, that is to say any request that is not of the GET method. The remaining methods mostly used in RESTful routing; PATCH, POST, PUT and DELETE should all impact a change on the data in your application. For this reason they should all have CSRF protection applied to them, and there are a couple of ways to go about it in Laravel.

The first way is to implement the CSRF filter provided by Laravel within your routes file. You're welcome to go ahead an apply it to certain routes individually or different groups of routes as you see fit, but the easiest way (and only way I'll cover here) is just to pop this somewhere (probably at the top):

Route::when('*', 'csrf', ['delete', 'patch', 'post', 'put']);

What this will do is apply the CSRF filter to any request of any of the non-idempotent request types. The other way, which I'm also a little fond of as it does provide a little more flexibility. We simply apply the filter into the BaseController contstructor.

class BaseController extends Controller {
    public function __construct()
	    $this->beforeFilter('csrf', ['on' => ['delete', 'patch', 'post', 'put']]);

This makes it easy to override in child controllers, and a part of me also feels that filters belong more in the controllers - but that could just be my Rails side coming out. Pick a way that works for you, as long as you are using CSRF protection as opposed to none at all!

A blog about Laravel & Rails,
written by Dwight Watson.