Securing Craft

There are many things that you should do to ensure your Craft install is as secure as possible.

Do not enable Dev Mode in a production environment #

Dev Mode is meant to help during local development and should not be enabled in a production environment, where it can cause a wide range of security issues.

Place your project’s source folder above your webroot #

The safest way to ensure that Craft’s PHP files and other sensitive information are not directly accessible over HTTP traffic is to put your project’s source folder above your webroot.

If you used the Composer starter Craft project and haven’t modified the folder structure, you are already covered.

If you have to put your source folder in webroot, you should ensure that users cannot directly access the contents of any files/folders in that folder. Craft ships with a .htaccess and a web.config file that denies access, but if you’re using Nginx or Apache/IIS isn’t configured to parse .htaccess/web.config files, you’ll need to take extra steps to secure the files.

Set allowAdminChanges to false in production #

By setting allowAdminChanges to false in production, it disables even administrators from making Craft system settings changes in production. The Settings and Plugin Store sections are hidden, the Craft edition and Craft/plugin versions will be locked, and the project config will become read-only.

Setting this to false makes production a more predictable and stable environment, and it prevents a host of potential security concerns should an administrator account be compromised.

Explicitly set the @web alias for the site #

You should explicitly set the @web alias to the site’s domain to help avoid host header attacks on loosely configured web servers.

Install an SSL certificate and enforce it #

If you don’t have an SSL certificate, talk to your host about installing one. Once you have one in place, you should, at a minimum, enforce that all control panel traffic gets sent over SSL. Ideally, front-end traffic should use SSL, especially when sensitive information is transmitted to/from the server.

Don’t blindly trust front-end user input #

If you accept front-end user input on your site, don’t trust it. It should be escaped and/or sanitized before it’s displayed anywhere. This is especially true for front-end user-supplied files that can be uploaded.

Audit the allowedFileExtensions config setting #

You should audit the allowedFileExtensions config setting to remove any file extensions you know will not be uploaded to your site, either via the Control Panel or the front-end. Craft does its best to sanitize things like images and SVG uploads to strip out any maliciously embedded code by default. Some files, PDFs for example, PHP can’t sanitize. If your site doesn’t need to allow PDF uploads, you can remove the extension from this config setting.

Enable all “Purify HTML?” Redactor field settings #

If you’re using the Redactor plugin, you should make sure the “Purify HTML?” Rich Text field setting is enabled. It will run its data through HTML Purifier on save. That will ensure no JavaScript code in the field’s value, preventing potential XSS vulnerabilities that could be used for permission escalation and various other exploits.

Enable CSRF protection #

Craft comes with Cross-Site Request Forgery (CSRF) features baked in. See Enabling CSRF Protection on how to secure your public-facing forms.

Make sure you’re running a recent version of PHP #

Craft 4 requires PHP 8.0.2 and supports the latest PHP versions. You can see which PHP versions are under active development and are supported by the core team. If possible, you should be running the latest PHP version your hosting provider supports.

Keep Craft and all of your installed plugins updated #

All software has bugs. Older software has more bugs. Some bugs are security vulnerabilities. Keep your software updated to have fewer security vulnerabilities.

Check your permissions #

Craft has recommended permissions for its files in the documentation, but you can lock them down more depending on how your server is configured. Here is a handy shell script you can use to configure and set permissions on a per-project basis on *nix based systems.

Make sure you trust anyone providing Twig anywhere in the system, whether it’s templates or control panel settings. Twig is powerful and can be used to do malicious things in Craft.

Review config settings on a per-site basis #

There are many Craft configuration settings that have security implications that should be reviewed on a per-site basis. Craft ships with reasonable defaults for them, but depending on the site requirements, they can be adjusted to be more secure.

Set security headers for the front-end site #

Your server should be configured to send these security headers:

A comprehensive list of security-related HTTP headers is maintained by OWASP.

You can run your domain through a site like securityheaders.io to check for recommended header settings.

X-Frame-Options could be overly-restrictive for multi-domain installs using live preview. See Using Live Preview With An Alternate Control Panel Domain for recommendations.

Other Things to Consider #

While less about actual security and more about security-through-obscurity, the following are things you might want to consider if you’re particularly paranoid:

Change your cpTrigger #

The cpTrigger config setting defines the name of the URI segment that points to the control panel. Changing it to a custom word will make it a little harder for visitors to find your control panel’s login page.

Remove the X-Powered-By header #

If you don’t want tools like BuiltWith and Wappalyzer to know your site is powered by Craft, you can set your sendPoweredByHeader config setting to false, which will prevent Craft from sending an X-Powered-By: Craft CMS header in its HTTP responses.

More Resources #

Here’s some other resources on the topic of security you might want to check out:

Applies to Craft CMS 4 and Craft CMS 3.