Imagine a world where packages are routinely delivered by drone. How long would it take for them to also be undelivered?

By this I mean, how cheap and ubiquitous would drone technology need to be for thieves to also program a fleet of drones tasked with automatically snatching up any package left unattended? Perhaps this question seems far-fetched. After all, the thieves would be caught, wouldn’t they?

Maybe, maybe not. But no drones need fly through the air for this thought experiment to be useful. Thieves already program bots to crawl the internet, looking for vulnerabilities to exploit. For example, they might scrape any AWS credentials that are committed into GitHub repositories, and use them to create nodes in a botnet.

I’m sure someone else has named this problem before, but I call it the Reverse-Delivery-Drone problem, after our hypothetical fleet of mechanized bandits, and it is a useful idea when considering the risk exposure of any asset on the public internet. You don’t have to be a target. You just need to be available, and someone will attack. Even if the attacks executed today are ineffective, or do not yet target your asset specifically, they could become effective in an instant, without any time to react, because the public internet is always connected.

Anything that can be automatically exploited by a computer with little consequence will be.

The Reverse-Delivery-Drone Problem

This weekend, I redeployed my website behind a firewall managed by Amazon Web Services. While the impact of my website being compromised would be low for me, I think it’s important for the infrastructure I use on my website to reflect the quality of work that I would produce for any client. And any entity that is concerned about the confidentiality, integrity, and availability of their web services ought to carefully consider their web infrastructure to make sure that it is both secure and resilient.

In this post I will outline my website’s new architecture for anyone who is interested in following along, or simply learning something new.

Give it a test drive

I’ve included two example URLs below that the firewall will intercept as potential attacks. Clicking on these will show an error page — this demonstrates the firewall doing exactly what it’s supposed to do.

SQL Injection Attack: https://blog.matteskridge.com/?query=” OR 1=1

HTML Injection Attack: https://matteskridge.com/?query=<script>alert(“Hello!”)</script>

These links would be safe to click even without the firewall, since they demonstrate attacks that neither your browser nor the website are vulnerable to, but could be dangerous in the right context, which is why the firewall blocks them.

Starting Point

Below we see a diagram of my website’s architecture before I made changes this weekend. Much of this is outlined in a previous blog post, with the caveat that I have since added continuous deployments for my portfolio website.

In particular, we see that:

  • The portfolio is an Angular2 single page application that is built and deployed to Cloudfront + S3.
  • The blog itself is powered by WordPress and hosted by DigitalOcean
  • Blog attachments are uploaded to and served up by Cloudfront + S3
  • DNS is managed by Hover, a domain registrar

This architecture has many upsides, but there are also significant vulnerabilities, which I aimed to mitigate through my latest round of changes

Vulnerabilities

Some vulnerabilities that are particularly noteworthy in the former setup:

  • The WordPress server is a PHP web application, so is inherently less secure than a completely static website. Even if WordPress itself works to fix new vulnerabilities, the following issues are still exposed:
    • The webserver could be misconfigured in some way
    • WordPress, Apache, or the Ubuntu operating system could fall out of date
    • The web server could be taken down by a denial of service attack or an unexpected increase in legitimate web traffic
  • The portfolio application was custom-developed by myself, so has not been subject to significant scrutiny by the open source community, as WordPress and Ubuntu have. Static sites are generally very resilient, but still can be used as a vector for novel attacks, such as leveraging the trust that an admin’s browser grants to a domain to execute a sensitive XHR request.

These are the issues that I aimed to mitigate with an adjusted architecture, which we see in the following section.

New Architecture

Below we see a diagram of the new architecture I implemented.

Notable changes include:

  • The WordPress server has been migrated from DigitalOcean to an Amazon EC2 instance
  • Cloudfront is used as a web cache in front of the wordpress server. It absorbs much of the traffic directed to it, decreasing the load that the server itself has to bear, and also distributing the content to global edge locations for faster access
  • Amazon WAF is used to filter connections to the website. Any connection that is identified as a possible attack is blocked, so that it cannot be executed on the source server or in the user’s browser.
  • Amazon Route 53 is used as DNS, offering more configurability than Hover

This architecture mitigates the most significant vulnerabilities identified in the previous section. The WordPress server is behind Cloudfront; since Amazon’s CDN has AWS Shield built in, it can absorb many denial or service attacks, and also handle a lot more traffic.

The new architecture also protects each publicly available asset with a Web Application Firewall. Amazon manages the block lists used here, so can adapt the rules to respond to emerging threats. Since WordPress is a very popular platform, and they offer a specific ruleset for it, they would likely patch a critical exploit before I could manage to update the server myself.

Cost Analysis

This project wouldn’t be complete without an analysis of the costs involved. After all, I’m paying for it! Below we see a breakdown of the recurring costs of hosting the website under both the old and the new architectures.

ItemPrev. CostNew Cost
matteskridge.com domain$1.25$1.25
WordPress server$10$7.49
Cloudfront traffic (projected)$1$2
Route 53 DNS (projected)$1
Amazon WAF (1 ACL)$5
Firewall: OWASP ruleset$1
Firewall: Bad inputs ruleset$1
Firewall: PHP ruleset$1
Firewall: Linux ruleset$1
Firewall: WordPress ruleset$1
Firewall: MySQL ruleset$1
Monthly total$12.25$22.74
Yearly total (nominal)$146.99$272.85
3 year operating life (discounted)$382.01$709.09

We see that the new architecture costs about twice as much, though it is still quite affordable; a single beefy Amazon EC2 instance would cost more than every component in the new architecture combined.

The 3 year lifetime cost was calculated by discounting the subscription payments at a effective annual rate of 10%. This number is useful to me, as it puts the monthly cost in perspective. I can expect to use this website setup for about 3 years; beyond that, technologies will likely change enough that I will be adopting a modified architecture.

Calculations:

Monthly expense = $22.74
Discount rate = 10%
Monthly discount rate = ((1+.10)^(1÷12))−1 = 0.8%
Lifetime cost = PV(0.8%, 3 * 12, -$22.74, 0)
Lifetime cost = $709.09

Note 1: For more information on this method of calculating value, see the Time Value of Money; 10% was selected as the appropriate discount rate as it approximates the historical annual return of the New York Stock Exchange, where the money might be otherwise invested.

Note 2: I’m assuming low levels of traffic in making this calculation. Should the website scale significantly, it would cost more, though the benefits of having more traffic woul make the additional costs well worth it.

We see that the difference in cost between the two approaches is $709.09 – $382.01 = $327.08. Is having this additional protection worth me paying $327.08 today? Perhaps; we can certainly see that firewall appliances retail for about the same price on Amazon.com.

So how do I set this up?

This architecture can be duplicated in AWS without much trouble. This post does not provide a comprehensive step-by-step, but the following will help get anyone interested moving in the right direction:

  • Refer to my previous blog post on setting up websites to duplicate the original architecture
  • Configure Cloudfront as a CDN that has the blog server as the origin
    • A custom header checked by a .htaccess file can be used to restrict inbound traffic to the blog server to only traffic from Cloudfront
    • The Cloudfront distribution should be configured to not cache anything at the /wp-admin* path (which you’ll use to write & edit posts); the cache and WordPress may need to be subtly adjusted to preserve specific features
    • Create an Access Control List (ACL) in the AWS Firewall Manager section of the AWS Management Console and associate it with your Cloudfront distribution. Select the rule groups that are most appropriate for your application, and adjust individual rules using overrides as necessary to preserve functionality

Conclusion

Managing a website brings a good deal of uncertainty, but cloud providers like AWS are working to mitigate it by providing powerful tools to anyone who needs them. Not long ago, the elements that I used in this infrastructure would have only been available to a large enterprise, if anyone at all.

If you have a website but haven’t set up a firewall or CDN yet, take a look around and see if any of the options fit your needs. Your users will thank you; after all, it protects them too.