Blog Post

Secure By Design

by: Simon Hughes
date: Thursday, Feb 21, 2019
category: my-technology hosting aws security cloudfront

I have always been aware that since I launched this site it had always been as secure as possible, since it is a static html website, hosted on a good provider with a very secure password. But can I do better?


There are some great tools available to scan a website and give you a security rating. is one I recommend to all my clients. This will check all the http headers that your website returns, and works out whether they are set correctly, and what you may be exposed to.

A quick scan of this site, yielded a terrible F. A large number of security headers were missing which means the site could be exposed to cross site scripting and other vulnerabilities. Time to fix it.

Since there really isn't any servers hosting this site, and everything is being done by serverless functions I pondered how to resolve this, typically if you had a dynamic site via Java, or .Net then it would be a simple solution, this however took a little more thought.

Once again though, Amazon and the amazing AWS plaform has the solution. Built into the CDN system CloudFront that delivers all the contents for this site, is the ability to run lambda functions. If you are a fan of serverless technology this will make sense. But lambda functions are the serverless way of running a piece of code on an adhoc basis.

After a quick session on Google to find out the correct syntax and language for running lambda functions, and I had the following NodeJS code written which will inject the correct http headers into a http response.

exports.handler = (event, context, callback) => {
    //Get contents of response
    const response = event.Records[0].cf.response;
    const headers = response.headers;

//Set new headers 
 headers['strict-transport-security'] = [{key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubdomains; preload'}]; 
 headers['x-content-type-options'] = [{key: 'X-Content-Type-Options', value: 'nosniff'}]; 
 headers['x-frame-options'] = [{key: 'X-Frame-Options', value: 'DENY'}]; 
 headers['x-xss-protection'] = [{key: 'X-XSS-Protection', value: '1; mode=block'}]; 
 headers['referrer-policy'] = [{key: 'Referrer-Policy', value: 'same-origin'}]; 
    //Return modified response
    callback(null, response);

Once the code was tested, it needed to be implemented as a lambda function. Over to the AWS console and click through to the Lambda section, and I can create a new function, and publish it. The code has to be created in the N.Virgina region to ensure its accessibleto the CloudFront service. Once the code is published, it can be hooked up into CloudFront.

Hopping over to the CloudFront distribution allows you to configure specific behaviours. Scrolling down the page, there is a section for Lambda functions, and selecting Origin Response and our function allows us to use our newly written function, every time we get a html page from the S3 service. The headers are then calculated, and the whole page is then cached. Before I can retest the site I had to quickly clear the cache on CloudFront, and then we are good to go.

A quick trip back to and we find we now have a nice shiny A rating for security. There is still more to do, as an A+ is available. One for another day as that requires a rewrite of the JavaScript in the site.

Related Blog Posts

The Quest for Superfast Hosting

Up until Feb 2019, my website was hosted on a third party hosting platform. This was a typical hosting scenario where you have a small website you need to host without spending a fortune.

Read More

Continuous Integration / Deployment

One of the key pieces of advice I give my clients is to automate as much as is reasonable. If you find any team member doing the same task a number of times then you should invest the time to automate it.

Read More

This Sites Technology

Today I thought it was worth writing a quick blog post to detail the technology I used to build this site, and why. Within the industry if you want a small site that's easy to update the default answer is WordPress. I do like to be different, and challenge the obvious to ensure the best results for my clients, so I pushed myself to find a better solution.

Read More