Skip to content
websitecontrole.nl
Advice

Tuning the security of a Craft CMS site

Craft gives you full control over your headers and your markup, so almost everything this check reports is yours to fix. Below, per finding, where the fix lives, with code you can copy.

Response headers (HSTS, clickjacking, MIME sniffing, referrer, permissions)

Set these in one place for the whole site. The most robust place is the web server (the server block on nginx, or a .htaccess on Apache), because then they also apply to files Craft never touches. To keep it in the application, a small module can add them to the Response object.

To do it without server config and fully inside Craft, the Sherlock plugin is a good choice. Sherlock sets the security headers and a CSP from the control panel, and scans your install for other security issues at the same time.

nginx (server block)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
A small Craft module (in init())
Craft::$app->response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
Craft::$app->response->headers->set('X-Frame-Options', 'SAMEORIGIN');
Craft::$app->response->headers->set('X-Content-Type-Options', 'nosniff');
Craft::$app->response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');

The Content-Security-Policy

A CSP is well within reach on Craft because you control the templates yourself. If you use nonces, set them per request. The Sherlock plugin mentioned above manages the CSP from the control panel; an SEO plugin such as SEOmatic can do it too.

  1. Set the policy in report-only first (the Content-Security-Policy-Report-Only header), so it breaks nothing but still reports what it would block.
  2. Collect the reports with a tool like Sentry, Report URI or URIports, or read them in your browser console.
  3. Allow what is legitimately blocked, until no real violations come in.
  4. Rename the header to Content-Security-Policy to enforce the policy.

The connection (HTTPS and the certificate)

Forcing HTTPS and the certificate are your host or CDN. Make sure http redirects to https and the certificate is valid and not expired. Most hosts and CDNs do this with a toggle or a free Let's Encrypt certificate.

Read more

DNS records (SPF, DMARC, DNSSEC, IPv6)

These sit apart from your site: they are records at your domain. Set them with your DNS provider or domain registrar, not in your CMS or on your host. SPF and DMARC govern who may send mail as your domain, DNSSEC signs your DNS, and IPv6 is the one where the host has to offer an AAAA record and a connection before you can add it.

Go deeper

Advice for another platform