Secure Custom Origin with Cloud Front custom header and AWS WAF

Somesh Srivastava
6 min readAug 21, 2021

Amazon CloudFront as we know is the content delivery service from AWS which in addition to its core functionality, provides security features like Field level encryption, TLS etc. as well as integration with AWS security services like IAM, AWS Web Application Firewall (WAF). Learn more about Amazon Cloud Front here.

Below figure shows how CloudFront delivers content to the users. It uses Edge locations (CloudFront POP) to cache the contents and deliver it to the users for better user experience. CloudFront speeds up the distribution of your content by routing each user request through the AWS backbone network to the edge location that can best serve your content. Read more here

How CloudFront works

We have seen customers using Amazon Cloud Front as content (static or dynamic) delivery service with S3 or custom origin. Although the Cloud Front is a managed service by AWS and is secure by design by the AWS global network security procedures.

But what if users try bypassing CloudFront and try accessing your origin content directly? There are ways to secure your Origin such as using Origin Access Identity with Bucket policy, if the origin is S3 and use Security Groups, NACLs, WAF to Allow/Deny specific traffic to custom origin like API Gateway , Application load balancer targeting EC2 or any other origin.

In this Blog post, I’ll walk you through how you can use Cloud Front Custom Header with AWS WAF to secure the custom origin - Amazon API Gateway.

The solution consists of below configurations:

  1. Amazon WAF ACL to block traffic not containing custom header in the request
  2. Amazon API Gateway with lambda integration and WAF ACL applied to it
  3. Create CloudFront distribution with a custom header
Solution architecture

Step 1 is to create a WAF ACL.

AWS WAF is a web application firewall that helps protect web applications or APIs against common web exploits and bots that may affect availability, compromise security, or consume excessive resources. AWS WAF gives control over how traffic reaches applications by enabling you to create security rules that control bot traffic and block common attack patterns, such as SQL injection or cross-site scripting. Learn more about AWS WAF here

Go to AWS WAF service, select the resource type you like to apply the WAF to. In this demo, I’m applying WAF on an API stage in Amazon API Gateway, hence selected the resource type as Regional and the API resource.

click Next and add a rule ‘Add my own rules and rule groups’ using rule builder. Here we need to create a rule to monitor the requests based on the a condition that If the request matches the Header key ‘x-origin-verify’ and exactly matches the header value (you can give any value or best way is to generate the random string programmatically).

Select the action to take when a request matches the statements above. In our case select ‘Allow’ because we want to allow all requests with this header & header value. Click ‘Add Rule’.

Now select the default web ACL action for requests that don’t match the above rule. We want to Block all requests which DO NOT match the rule:

Click Next, review and create Web ACL. We are all set to allow/block the requests on API Gateway.

Step 2 Lets now configure the API in Amazon API Gateway. For the simplicity, I have integrated a very simple lambda function:

API in Amazon API Gateway

My API is working fine:

Now, lets apply the Web ACL we created in step 1 to the API Gateway stage called test:

Step 3 is to create a CloudFront distribution with API Gateway as a custom origin and add the custom header in the origin setting.

Use API endpoint as the Origin domain name which CloudFront will recognize as custom origin. Origin path will be the API stage/API resource. Rest all setting you can configure as per your requirement.

Cloud Front distribution

Now the fun part, the Custom Header. Configure the CloudFront distribution with the exact same header key and value you have configured in the web ACL.

We have now configured the CloudFront to add custom header to the requests that it sends to the origin - API Gateway.

I have a domain name with PHZ in the R53, which I have used to create the A records and CNAMEs records for this CloudFront distribution and configured the same in the CloudFront distribution.

Route53 configuration

All set now!! Here is how this will work, I’ll send the request to API Gateway endpoint via CloudFront. Upon receiving the request, CloudFront will add the custom header in the request (the viewer (or user) of the request is not aware that the CloudFront is adding this header) and forwards it to the API Gateway where the WAF Web ACL is monitoring all the requests, with a rule which only Allows the requests having custom header name ‘x-origin-verify’ and the value we have set, all other requests will be Blocked.

If the user tries to bypass the CloudFront distribution somehow, and tries to access the API Gateway endpoint directly, the request will be Blocked by WAF since the request will not have the custom header in it.

Let’s TEST

I have hit the url in the browser and it successfully reaches to the API Gateway. Here CloudFront is adding the custom header to my request which goes successfully to the API Gateway and gets the response:

I have also used postman to show you that I’m not passing any header in the request from my side (CloudFront adds it) and it gets the successful response:

Now, lets see what happens if I try to bypass the CloudFront and accessing the API Gateway endpoint directly. Great! WAF works! My request is Blocked by WAF here, since there was no header ‘x-origin-verify’ and its corresponding value in the request.

Same test using Postman - Request Blocked by WAF.

Now, lets add the custom header and the value to the request to pretend that the request is coming from CloudFront. Good stuff! Request if Allowed by WAF.

In this blog, I explained and showcased how you can use CloudFront custom header along with WAF to secure the custom origin. If you want to learn more about custom header do read it here.

Please do let me know you queries and feedback on this post and let me know the use case you want me to explain with a demo.

I’ll write another blog on another interesting use case shortly.

Happy Learning!!

Stay safe!

--

--