I made a post in July 2021 regarding AWS CloudFront + security headers. Using AWS Cloudfront and Cloudfront Functions, security headers were injected in viewer responses; however, AWS Cloudfront natively supports security headers as of Nov. 2nd, 2021 alongside configurable CORS and custom HTTP response headers.
Cloudfront can natively support all the security headers from the last post:
- permissions-policy
- referrer-policy
- strict-transport-security
- x-content-type-options
- x-frame-options
- x-xss-protection
Begin with defining an aws_cloudfront_response_headers_policy
resource in Terraform. This resources contains all the header policy information. In the following example, the values for each security_headers_config
were copied from AWS’s documentation.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| resource "aws_cloudfront_response_headers_policy" "headers_policy" {
name = "security-headers-policy"
custom_headers_config {
items {
header = "permissions-policy"
override = true
value = "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()"
}
}
security_headers_config {
content_type_options {
override = true
}
frame_options {
override = true
frame_option = "DENY"
}
referrer_policy {
override = true
referrer_policy = "same-origin"
}
strict_transport_security {
override = true
access_control_max_age_sec = 63072000
include_subdomains = true
preload = true
}
xss_protection {
override = true
mode_block = true
protection = true
}
}
}
|
Attach it to a Cloudfront Behavior. In this case, I attached it to the default_cache_behavior
block.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| locals {
cloudfront_origin_id = "s3"
}
resource "aws_cloudfront_distribution" "distribution" {
aliases = var.domain_names
enabled = true
origin {
domain_name = aws_s3_bucket.bucket.bucket_domain_name
origin_id = local.cloudfront_origin_id
}
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
compress = true
target_origin_id = local.cloudfront_origin_id
viewer_protocol_policy = "redirect-to-https"
response_headers_policy_id = aws_cloudfront_response_headers_policy.headers_policy.id
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
}
|
Once your infrastructure is deployed, AWS CloudFront will forward security headers. To see this in action, refer to the how.wtf
repository.