Using Varnish To Tweak Your Http Responses

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 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. 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:

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 is for.

Let’s start with the code

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) 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()

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 account and see just how easy it can be to get Varnish running in front of your website.

Blog Categories

Interested in articles about a specific topic? Click on a category to see all related content. Sign up

Want to get started improving your website performance, scalability, and security? Sign up for a 14 day free trial of and see what we can do for you!

Get started