Varnish is an excellent caching application, it’s what it’s designed for after all. However the fact that it ships with a built-in programming language (VCL) makes it very useful for tweaking how your site responds to HTTP requests. Often these can be things that you don’t really want your website to be concerned with, like sending some standard HTTP headers. Also it’s great for stopping unwanted requests from getting to your webserver, e.g. enforcing HTTPS.

Customising response headers

There are a number of HTTP response headers that your site should send to assist with securing your site. A great place to start is to go to https://securityheaders.io and scan your site and see what recommendations it has. Here are a few that it would be good to set:

  • X-Frame-Options - Don’t let your site be put inside a frame on another domain
  • X-XSS-Protection - Enables the browser’s built-in Cross-Site Scripting (XSS) protection
  • X-Content-Type-Options: Stops the browser from trying to guess what content-type a response is (Content Sniffing) and forces it to use the Content-Type header sent.
  • Strict-Transport-Security - If you’ve decided to make your site HTTPS only, setting the Strict-Transport-Security header which means the browser will enforce HTTPS for you. You can read more on STS on Scott Helme’s site
  • Content-Security-Policy - Define a list of approved sources of content that a browser can load, good for preventing XSS attacks. https://report-uri.io/ will help you generate the content for this header.

It’s also a good idea to unset the server header. Knowing what server your site is running on makes attacking it easier.

It may be fiddly to get your app to respond correctly with these headers, especially for static files that may not run through you app code pipeline. Or perhaps your site consists of multiple applications and you’d have to replicate your code across all the apps. It’s much easier to implement in VCL:

{% gist section-io-gists/39e0ddc31cdd7ca8ae33 %}

Demonstration on vclFiddle

Enforcing HTTPS

This is something you don’t want to have to worry about in your app code, as it’s a redundant request making it all the way to your webserver just to be told to come back and try again. Shielding your server from this kind of redundancy is just what Varnish Cache is for.

Let’s start with the code

{% gist section-io-gists/02dba4113b8caf5da473 %}

Demonstration on vclFiddle

So all this is doing is checking if the request has an X-Forwarded-Proto header of https and if it doesn’t return a synthetic response (i.e. one that wasn’t proxied from a backend, but was generated synthetically by Varnish Cache) of a 301 redirect to the HTTPS version of the url requested.

Blocking requests

You may want to block access to you webserver for certain types of requests. Maybe you have a misbehaving bot that is hitting your site, it’s not respecting your robots.txt and going places it shouldn’t or hitting you too often.

Similar to the way we enforced HTTPS, we can immediately block requests we don’t like using synth()

{% gist section-io-gists/12e0e35369e3b95ed996 %}

Demonstration on vclFiddle

We don’t need to customise the response headers, so the additional vcl_synth call was not needed. Obviously this is not going to stop malicious attackers, but it can be useful to stop unintentionally misbehaving bots.

This is just a start as far as security for your site is concerned but it can help stop a lot of the more common attacks on your users. Why not setup a Section account and see just how easy it can be to get Varnish Cache running in front of your website.

Similar Articles