How I built the most secure static site on Amazon S3

Web application attacks have been on a steady rise over the past few years to the point where some attacks have left some organizations completely crippled on the front end side. Attacks like DNS poisoning which redirects DNS queries to another server that isn’t the primary one have caused huge financial losses and reputational damage.

Why did I build the site on AWS?

When I started building my demo static site, I made security an ingredient and not an afterthought to make the site secure and bulletproof from past present and future attacks. the most secure place to do it was AWS as they have a unique cocktail of security product solutions that help with this.

I uploaded all the static site content to an S3 bucket and used route 53 for DNS resolution and cloud front for CDN.

How I implemented security on AWS.

Since I didn’t want to go through the whole process of writing HTML, and CSS code for my static demo site I went to Replit and copied one of their demo static site templates and uploaded its contents to my S3 bucket. while creating the bucket I ensured I didn’t unblock all public access which is blocked by default.

I choose this approach as a security feature as I will enable public access from Cloudfront which is best practice, more on this later. I also used a customer-managed encryption key from KMS to be able to manage keys by myself as the default S3 encryption SSE-S3 doesn’t allow you to manage keys and reduce the cost of KMS API calls by the CMEK  I enabled bucket keys which reduce AWS KMS costs by up to 99% on S3.

I had my static site domain registered on another host so I changed the nameservers in my domain registrar to route53 nameservers and reduced the TTL to 1 min to ensure faster propagation. As a security feature in route 53 I enabled DNSSEC signing that uses a key signing key which is a cryptographic public-private key that is stored in KMS.DNSSEC blocks various types of DNS attacks, including the DNS poisoning that I mentioned earlier.

creation of the Cloudfront distribution was the next step and this is where I allowed the distribution origin access identity to access my S3 bucket directly. CloudFront creates a bucket policy attached to my S3 bucket that adheres to the principle of least privilege. In the cloud front distribution settings, I enabled security protections AWS WAF which blocks cross-site scripting, and SQL injections among other attacks. I also requested an SSL certificate from the certificates manager for my domain. As I mentioned earlier allowing your bucket to be accessed from the Cloudfront is a security best practice and should always be considered as compared to enabling public access which exposes all your bucket’s contents.

challenges faced during the build and how I overcame them

During the build, I faced challenges like permission issues that were solved using IAM but the main problem was adding a service quota limit to my CloudFront distribution as it wasn’t enabled for my resolve this head over to support, create a new case on the top right click looking for service quota increases.

✅for the service select CloudFront distributions from the drop-down menu

✅in the quota section and search for web distribution per account

describe your case in the case description section and submit it. speed of resolution depends on the support plan you are using if you are on the basic support plan it takes longer like in my case it took more than 24 hours before an AWS support representative looked into my issue but I am sure other support plans get sorted out quickly as they are a paid service.

Leave a Comment