After you've hardened your site with appropriate TLS, what's next? Correct answer: HTTP security headers!
Security headers let you use built-in security features of modern browsers that are turned off by default, not to break old sites. A lot of these headers exist as much or more to protect your visitors rather than your site itself.
If you want to know the status of your headers, use the excellent scanner on https://securityheaders.com. If there actually was a security headers exam for sites, that would be it. A lot of this blog post also comes from the site of Scott Helme, the maker of securityheaders.com - a lot of credit to him.
1. HSTS - HTTP Strict Transport Security
The Strict-Transport-Security header disallows the visitor's browser to connect to your site using plain old HTTP. This could avert man in the middle attacks de-/reencrypting contents in transit.
Protects against: protocol downgrade attacks and cookie hijacking.
Strict-Transport-Security: max-age=31536000; includeSubDomains
2. CSP - Content Security Policy
Getting your existing site to work with a strict CSP can be a lot of work. The biggest gripe is getting rid of 'unsafe-inline' when using CMS platforms like WordPress or Ghost, or with bothersome third-party add-ons. Currently 'unsafe-inline' is actually active on this site (shh, don't tell anyone) only because Disqus doesn't work without it. One more item on the cons list for Disqus, which I'll be replacing. So currently, Disqus is preventing me from going from A to A+ on securityheaders.com.
Protects against: cross site scripting (XSS) and script injections.
Content-Security-Policy: script-src 'self' 'unsafe-inline' code.jquery.com www.googletagmanager.com www.google-analytics.com metalcoder.disqus.com c.disquscdn.com disqus.com; object-src disqus.com
The above allows inline scripts and scripts loaded from a list of named domains.
The good thing about CSP is that you can dry run it using the header Content-Security-Policy-Report-Only. Using that header, your browser will load all content but show warnings in the console about what would be blocked if used the actual CSP header. This is extremely useful since constructing the right CSP header can be very complicated and if you use the live one (without Report-Only) it can be hard to see what doesn't load properly.
3. Referrer Policy
Referrer policy controls what information is included when a visitor clicks on a link going out of your site. Why do you want to restrict this information? Well, for one thing if your site isn't public it doesn't make sense to relay your internal URLs to a third party. On this site, I'm fine with that (it might even generate some traffic), so I opted to send referrer info, but only when the target site uses TLS.
Protects against: divulging internal information about your site
Read more about Referrer Policy
4. Content Type Options
There's only one setting for X-Content-Type-Options: nosniff. That makes the browser always use the content-type you've set for a resource instead of what the browser might think it should be.
Protects against: accidentally treating user-uploaded files as executables
Read more about Content-Type-Options
5. Frame Options
X-Frame-Options tells the browser where, if anywhere, your site should be allowed in an iframe. For this blog I'm using SAMEORIGIN, since the Ghost editor shows a preview of the site in an iframe.
Protects against: your site being hijacked and shown as a part of other sites.
6. XSS Protection
X-Xss-Protection protects against... yes, cross-site scripting. You can set it to 1 to activate it and to 1; mode=block to have it completely block scripts instead of trying to make them safe by sanitation.
Protects against: your visitors getting malicious scripts run using your site
X-Xss-Protection: "1; mode=block"
Read more about XSS Protection
7. Feature Policy
Feature-Policy is the newest member of the HTTP security headers family. It regulates which browser external features a site wants to white-list. Examples of such features are vibrations, camera, microphones and accelerometer.
I didn't actually get around to setting this header on this blog, at least not yet. It's not widely implemented in browsers yet.
Protects against: unintended use of device features, like spying through the camera, using your site.
Feature-Policy: vibrate 'self'; usermedia *; sync-xhr 'self' https://example.com
Read more about Feature Policy
There's an online validator for your CSP header, which is the trickiest one to get right: https://cspvalidator.org/#url=https://heavymetalcoder.com/
Apart from that, keep running securityheaders.com until you get an A.