The checklist
Security headers: an example
Headers are instructions the server sends to the browser together with the page. They say, for example, where scripts may be loaded from and whether the page may be embedded in someone else's frame. These are the headers of this site (in the Netlify _headers file format; on other servers the syntax differs but the values are the same):
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none' Strict-Transport-Security: max-age=63072000; includeSubDomains X-Content-Type-Options: nosniff X-Frame-Options: DENY Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: camera=(), microphone=(), geolocation=()
- Content-Security-Policy
Tells the browser where scripts, styles and images may be loaded from. An injected foreign script won't run.
- Strict-Transport-Security
The browser always connects over HTTPS, even when someone types the address with http.
- X-Frame-Options and frame-ancestors
Block embedding the page in someone else's frame, the basis of the “click here, but you're really clicking there” attack.
- X-Content-Type-Options
The browser doesn't guess the file type, so an image won't be executed as a script.
Content-Security-Policy has to be tailored to the site: if it uses external scripts (analytics, chat, maps), they must be on the list. A badly set policy can switch off part of the site, so test it before deploying.
Free tools for checking
- securityheaders.com
A rating of the security headers with an explanation of what's missing.
- developer.mozilla.org/observatory
A broader rating of the HTTPS and header configuration from Mozilla.
- DMARC checking tools
They show whether your domain's SPF, DKIM and DMARC records are correct.
- PageSpeed Insights
Not about security, but along the way it shows outdated libraries and third-party scripts.
Terms from this guide
- HTTPS
An encrypted connection between the browser and the site. It protects data from being read or swapped on the way.
- HSTS
A header that tells the browser to always connect to the site over HTTPS, even when someone types the address with http.
- Content-Security-Policy
A header that tells the browser where a page may load scripts, styles and images from. It blocks injected, foreign scripts from running.
- Two-factor sign-in (2FA)
Signing in that requires a second confirmation besides the password, for example a code from an app. A stolen password alone isn't enough to take over the account.
- Static site
A site made of ready files, without a database or login panel on the server. Fast and harder to attack, but content changes require rebuilding it.
Questions and answers
Is a small company website even a target?
Yes, but usually not personally. Bots scan the whole internet for known holes in popular plugins and weak passwords. A hijacked site is then used to send spam or run scams.
Is a static site more secure?
It has a smaller attack surface, because there's no login panel, no database and no plugins to update. The hosting and domain accounts still need protecting.
What should I do if the site has been hijacked?
Change the passwords and turn on two-factor sign-in on all accounts, restore the site from a clean backup, update everything, and then find out how they got in so they don't come back the same way.
Sources and documentation
- OWASP Top 10: the most common web application security flawsowasp.org
- MDN HTTP Observatory: a header testdeveloper.mozilla.org
- Security Headers: a header testsecurityheaders.com
- MDN: Content-Security-Policydeveloper.mozilla.org
- MDN: Strict-Transport-Securitydeveloper.mozilla.org
- The HSTS preload listhstspreload.org
- CERT Polska: incident reporting and warningscert.pl