Enabling CSRF Protection

Craft has built-in protection against Cross-Site Request Forgery attacks (CSRF) that’s enabled by default in Craft 3’s enableCsrfProtection config setting in config/general.php:

'enableCsrfProtection' => true,

With CSRF protection enabled, all of your site’s visitors will get a “CRAFT_CSRF_TOKEN” cookie set on their browser, and all POST requests must be accompanied by a POST parameter with a matching name and value (the CSRF token). If they aren’t, Craft will reject the request with a 400 error.

Craft handles the cookie creation automatically, but it’s up to you to start passing the CSRF token along with your POST requests.

Updating your HTML forms #

Anywhere you have a <form> with the attribute method="post", you will need to add this inside it:

<input type="hidden" name="{{ craft.app.config.general.csrfTokenName }}" value="{{ craft.app.request.csrfToken }}">

Craft comes with a csrfInput() function that gives you the same thing:

<form method="post">
    {{ csrfInput() }}
    <!-- ... -->
</form>

Be careful not to use csrfInput() inside a {% cache %} tag!

Updating your JavaScript #

If you have any JavaScript that’s creating POST requests, you will need to make sure those are passing the CSRF token as well. You will need to set the token name and value in JavaScript before any scripts are loaded that will need to use it, so your main layout template might look something like this:

<script type="text/javascript">
    window.csrfTokenName = "{{ craft.app.config.general.csrfTokenName|e('js') }}";
    window.csrfTokenValue = "{{ craft.app.request.csrfToken|e('js') }}";
</script>
<script type="text/javascript" src="path/to/script.js"></script>

If you’re using jQuery.ajax() or jQuery.post() to create POST requests over Ajax, you can pass the CSRF Token along with the request by adding it to the object you pass as the function’s data argument:

var data = {
    // ...
};

// Add the CSRF Token
data[csrfTokenName] = csrfTokenValue;

$.post('/some/url', data, function(response, textStatus, jqXHR) {
    // ...
});

Applies to Craft CMS 3.