Networking & Content Delivery

Customize 403 error pages from Amazon CloudFront Origin with Lambda@Edge

AWS Web Application Firewall (AWS WAF) is commonly used to protect HTTP and HTTPS requests forwarded to Amazon CloudFront. When you are using this approach, default 403 error pages do not distinguish whether the error came from AWS WAF or the CloudFront Origin.

As an AWS WAF and Amazon CloudFront user, you may want to customize your end-user experience for the HTTP 403 error based on whether the request was blocked by AWS WAF (unauthorized access) or by the Origin (page not found at the Origin).

In this blog, you will learn how to use Lambda@Edge functions to display customized error pages, or mask 4XX error pages, based on where the error originated.

Problem statement

End-users only receive the default HTTP 403 error page. Figure 1: End-users only receive the default HTTP 403 error page.

In the preceding architecture, the example customer has set up AWS WAF on Amazon CloudFront distribution. Currently, the customer cannot show their end-user’s client a custom error page based on whether the request is blocked by AWS WAF (AWS WAF 403 error) or whether the requested resource is forbidden by the Origin (Origin 403 error).

Proposed solution

The end-user error page is customized based on origination using Lambda@Edge functions. Figure 2: The end-user error page is customized based on origination using Lambda@Edge functions.

In the proposed solution, the example customer can customize the response for HTTP 403 error coming from the Origin using Lambda@Edge functions. For the HTTP 403 error coming from AWS WAF, the solution displays the default error page set in the CloudFront distribution.

Here is how the solution in Figure 2 works:

  1. End-user client sends a request to Amazon CloudFront, which forwards the request to the Origin(S3).
  2. Origin responds with a 403 Error Code back to the end-user client.
  3. Lambda@Edge function is invoked on origin response.
  4. Lambda@Edge redirects the requests with 302 status code to 404 error page (The error page can be customized as per you use case) which is sent as a response to the end-user client.

Solution deployment

1) Create the Lambda function.

The Lambda function is triggered on every origin response. You can configure it to check the response status code. In this case, if the response contains any error from 400 to 599, it redirects the response to the 404.html file. The following is a snippet in Python 3.7 that does the redirect.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import json

def lambda_handler(event, context):
response = event['Records'][0]['cf']['response']
request = event['Records'][0]['cf']['request']

'''
This function updates your HTTP status code in the response to a 404, redirecting it to another path (cache behavior) that has a different origin configured. Note the following:
1. The function is triggered by an origin response
2. The response status from the origin server is an error status code (4xx)
'''

if int(response['status']) >= 400 and int(response['status']) <= 499:
redirect_path = '/404.html'

response['status'] = 302
response['statusDescription'] = 'Found'

# Drop the body as it is not required for redirects
response['body'] = ''
response['headers']['location'] = [{'key': 'Location', 'value': redirect_path}]

return response

2) Configure the Lambda function that is invoked by an Amazon CloudFront Origin response.

This will ensure that the Lambda function is triggered every time a response is returned from the origin. Once the Lambda function is triggered, it checks the origin response status code and redirects if needed.

Go to the Lambda function, Add trigger, Choose Amazon CloudFront as the Trigger Configuration and Select Deploy to Lambda@Edge.

In Deploy to Lambda@Edge, ensure you have selected your Amazon CloudFront distribution ARN and chosen the Amazon CloudFront event as Origin Response.

Once you have successfully configured the Lambda trigger, the configuration looks as follows in the Amazon CloudFront Monitoring section.

Conclusion

Amazon CloudFront provides the ability to create custom error pages and to change response codes. In this blog, you learned how to customize your end-user experience for the HTTP 403 errors using Lambda@Edge.If you’re new to Amazon CloudFront and Lambda@Edge, refer to Getting Started with Amazon CloudFront and Getting Started with Lambda@Edge documentation for more information.

Thanks for reading this blog post!

About Us

Sonakshi Pandey

Sonakshi Pandey

Sonakshi Pandey is a Solutions Architect at Amazon Web Services, where she designs large scale distributed solutions with sole focus of migrating applications, software, and services on AWS. Prior to her cloud journey, she worked as a software engineer for the Amazon Forecasting Platform team.

Anuj Butail

Anuj Butail

Anuj Butail is a solutions architect at AWS. He is based out of San Francisco and helps customers in San Francisco and Silicon Valley design and build large scale applications on AWS. He has expertise in the area of AWS, edge services, and containers. He enjoys playing tennis, watching sitcoms, and spending time with his family.