1

I am using this doc https://aws.amazon.com/blogs/networking-and-content-delivery/adding-http-security-headers-using-lambdaedge-and-amazon-cloudfront/

I am using a react app in S3 bucket, with a cloudfront CDN. I have added a lambdaedge to add a security header

 headers['x-frame-options'] = [{key: 'X-Frame-Options', value: 'DENY'}]; 
 headers['x-xss-protection'] = [{key: 'X-XSS-Protection', value: '1; mode=block'}];

It is working fine for the homepage (mySite.com): enter image description here

But it doesn't work for a different route, example mySite.com/login enter image description here

When I check the error behavior in cloudFront, there are no options to add a header

enter image description here

Why this page /login is in error? Because of react router doesn't work in aws s3 bucket

Alan
  • 9,167
  • 4
  • 52
  • 70

2 Answers2

1

The way that I solved this was to implement an origin request Lambda@Edge function that validates the event.Records[0].cf.request.uri value against a whitelist of known files and paths in the S3 origin. If the path doesn't match the whitelist, it updates the uri value to /index.html which allows the React app handle the request.

With this change, there will no longer be any 404 requests, which means the response will successfully pass through the origin response Lambda@Edge function which adds the response headers.

kldavis4
  • 2,177
  • 1
  • 22
  • 33
1

We solve this by using this feature called policy response headers in cloudfront. It add headers in all cases even in error response.

Doc: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-response-headers-policies.html

We implemented it with terraform

resource "aws_cloudfront_response_headers_policy" "my_name" {
  name    = "policy-response-headers-my-name"
  comment = "Add security headers to responses"

  security_headers_config {

    xss_protection {
      mode_block = true
      override   = true
      protection = true
    }
    frame_options {
      frame_option = "DENY"
      override     = true
    }
    content_type_options {
      override = true
    }
    content_security_policy {
      content_security_policy = "frame-ancestors 'none'"
      override                = true
    }
    referrer_policy {
      referrer_policy = "same-origin"
      override        = true
    }
    strict_transport_security {
      access_control_max_age_sec = 63072000
      override                   = true
    }
    origin_override = true
  }
}
Alan
  • 9,167
  • 4
  • 52
  • 70