Laravel Tutorials

Cloudflare Turnstile versus CSRF tokens

Published Updated
Cloudflare Turnstile versus CSRF tokens image

I'm on a quest to improve the load times for laravelshift.com. I reached over 90% caching by focusing on my highest traffic content pages. Now I have a few relatively high traffic forms I want to cache. These are the Can I Upgrade Laravel and Convert curl to Http.

As forms within a Laravel application, I naturally add a CSRF token via the @csrf Blade directive. Underneath this inserts a hidden <input> field on the page with a unique, random value. This value is also added to the user's session.

Since it relies on the session, the CSRF token creates dynamic content on the page. As such, it's not cacheable. Or at least if I did cache it, users would get a 419 error upon submission. In order to make the page cacheable, I'd need to remove the CSRF token.

This got me asking, Do I need the CSRF token? Part of me thought CSRF tokens help prevent SPAM. But that's not really their intent. CSRF stands for Cross-Site Request Forgery. This token aims to prevent another site from submitting data or taking actions on your user's behalf. For example, submitting a request to deleted one of your Forge servers.

That's the theory. In code, it means we add a token to the form data. Upon submission, this token is validated against the one in the user's session. If it doesn't, Laravel rejects the submission. What if we could add something else to the form. Something that didn't rely on the session, but still provided some kind of security.

Enter Cloudflare Turnstile. Turnstile adds a challenge to the page. It can be visible to the user or invisible. When invisible it does some "work" in the background with JavaScript. Most bots can't perform this work. So they fail the challenge.

Since Turnstile uses JavaScript, it loads client side. Therefore making the page cacheable. This was a win-win for me. First, I can cache the high traffic forms. Second, I gained some SPAM prevention. Turnstile is much better at this using a challenge, and also with its collective intelligence.

Now, as always, there is a tradeoff. CSRF and Turnstile serve different purposes. For my case, these are public forms (unauthenticated). So I don't care if someone forges their submission from another site. Furthermore, Turnstile is configured by domain. So the challenge wouldn't run from another site. Meaning the form data would have a missing or incorrect value.

In the end, while Turnstile likely increased my SPAM protection, I accept any risk I may have introduced by removing the CSRF token. Having these forms cacheable was more important. In doing so, laravelshift.com is now 98% cached.

If you're interested in implementing Cloudflare Turnstile I used ryangjchandler/laravel-cloudflare-turnstile. There's a good write up in a previous Laravel News article.

If you're interested in making your Laravel apps respond crazy fast, check out my Fast Laravel video course.

Sponsored

laravelcloud logo
Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Visit Laravel Cloud

The latest

View all →
Taylor disabled GitHub Issues on most Laravel open-source packages. image

Taylor disabled GitHub Issues on most Laravel open-source packages.

Read article
Exclude Vendor and Default Commands in `php artisan dev` image

Exclude Vendor and Default Commands in `php artisan dev`

Read article
The Laracon Archive image

The Laracon Archive

Read article
Group Adjacent Collection Items in Laravel with chunkBy() image

Group Adjacent Collection Items in Laravel with chunkBy()

Read article
Laravel queue:work Now Prints Why the Worker Stopped image

Laravel queue:work Now Prints Why the Worker Stopped

Read article
Sidecar Brings Statamic's Control Panel to Your Existing Markdown Sites image

Sidecar Brings Statamic's Control Panel to Your Existing Markdown Sites

Read article