如何将 headers 添加到 CloudFront 响应?
How to add headers to CloudFront response?
我使用 https://observatory.mozilla.org/analyze 测试我的网站,我得到了 F 分数。
原因是:
Content Security Policy (CSP) header not implemented
X-XSS-Protection header not implemented
X-Frame-Options (XFO) header not implemented
...
我使用 CloudFront 为我的网站提供服务。
我把那些丢失的 headers 放到 CloudFront 的什么地方?
我建议使用 Lambda@Edge 将您要查找的任何 headers 添加到您的原始响应,然后再将其返回给查看者。
作为原始响应事件添加时,可以像下面的示例一样简单地完成。
import json
def lambda_handler(event, context):
response = event["Records"][0]["cf"]["response"]
headers = response["headers"]
headers['strict-transport-security'] = [{key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubdomains; preload'}];
headers['content-security-policy'] = [{key: 'Content-Security-Policy', value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"}];
headers['x-content-type-options'] = [{key: 'X-Content-Type-Options', value: 'nosniff'}];
headers['x-frame-options'] = [{key: 'X-Frame-Options', value: 'DENY'}];
headers['x-xss-protection'] = [{key: 'X-XSS-Protection', value: '1; mode=block'}];
headers['referrer-policy'] = [{key: 'Referrer-Policy', value: 'same-origin'}];
response['headers'] = headers
return response
有关详细信息,请查看 Adding HTTP Security Headers Using Lambda@Edge and Amazon CloudFront 博客 post。
2021 年 6 月 23 日更新
刚发现虽然下面的解决方案看起来不错,但它可能不够好,尤其是在增加安全性方面headers,因为如果 Cloudfront 从源头收到错误,将不会调用该函数
HTTP status codes
CloudFront does not invoke edge functions for viewer response events when the origin returns HTTP status code 400 or higher.
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-functions-restrictions.html
截至 2021 年 5 月,新推出的 Cloudfront 功能似乎是更好的选择,根据这篇博文,它的价格是 Lambda@Edge 的 1/6 https://aws.amazon.com/blogs/aws/introducing-cloudfront-functions-run-your-code-at-the-edge-with-low-latency-at-any-scale/
文档中的示例
function handler(event) {
var response = event.response;
var headers = response.headers;
// Set HTTP security headers
// Since JavaScript doesn't allow for hyphens in variable names, we use the dict["key"] notation
headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'};
headers['content-security-policy'] = { value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"};
headers['x-content-type-options'] = { value: 'nosniff'};
headers['x-frame-options'] = {value: 'DENY'};
headers['x-xss-protection'] = {value: '1; mode=block'};
// Return the response to viewers
return response;
}
如果您现在正在实施此功能,那么您很幸运。从 2021 年 11 月开始要简单得多。亚马逊通过响应 header 策略在本地添加了安全性 header,即我们不必创建 lambda 来仅向应用程序添加响应 header。
细节
https://aws.amazon.com/blogs/networking-and-content-delivery/amazon-cloudfront-introduces-response-headers-policies/.
Terraform AWS 提供商已从 3.64.0 开始支持 aws_cloudfront_response_headers_policy
https://github.com/hashicorp/terraform-provider-aws/blob/main/CHANGELOG.md#3640-november-04-2021.
这是一个通过 terraform aws 提供商向 aws 云端响应添加安全性 header 的示例。
resource "aws_cloudfront_response_headers_policy" "security_headers_policy" {
name = "my-security-headers-policy"
security_headers_config {
content_type_options {
override = true
}
frame_options {
frame_option = "DENY"
override = true
}
referrer_policy {
referrer_policy = "same-origin"
override = true
}
xss_protection {
mode_block = true
protection = true
override = true
}
strict_transport_security {
access_control_max_age_sec = "31536000"
include_subdomains = true
preload = true
override = true
}
content_security_policy {
content_security_policy = "frame-ancestors 'none'; default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"
override = true
}
}
}
我使用 https://observatory.mozilla.org/analyze 测试我的网站,我得到了 F 分数。
原因是:
Content Security Policy (CSP) header not implemented
X-XSS-Protection header not implemented
X-Frame-Options (XFO) header not implemented
...
我使用 CloudFront 为我的网站提供服务。
我把那些丢失的 headers 放到 CloudFront 的什么地方?
我建议使用 Lambda@Edge 将您要查找的任何 headers 添加到您的原始响应,然后再将其返回给查看者。
作为原始响应事件添加时,可以像下面的示例一样简单地完成。
import json
def lambda_handler(event, context):
response = event["Records"][0]["cf"]["response"]
headers = response["headers"]
headers['strict-transport-security'] = [{key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubdomains; preload'}];
headers['content-security-policy'] = [{key: 'Content-Security-Policy', value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"}];
headers['x-content-type-options'] = [{key: 'X-Content-Type-Options', value: 'nosniff'}];
headers['x-frame-options'] = [{key: 'X-Frame-Options', value: 'DENY'}];
headers['x-xss-protection'] = [{key: 'X-XSS-Protection', value: '1; mode=block'}];
headers['referrer-policy'] = [{key: 'Referrer-Policy', value: 'same-origin'}];
response['headers'] = headers
return response
有关详细信息,请查看 Adding HTTP Security Headers Using Lambda@Edge and Amazon CloudFront 博客 post。
2021 年 6 月 23 日更新
刚发现虽然下面的解决方案看起来不错,但它可能不够好,尤其是在增加安全性方面headers,因为如果 Cloudfront 从源头收到错误,将不会调用该函数
HTTP status codes CloudFront does not invoke edge functions for viewer response events when the origin returns HTTP status code 400 or higher.
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-functions-restrictions.html
截至 2021 年 5 月,新推出的 Cloudfront 功能似乎是更好的选择,根据这篇博文,它的价格是 Lambda@Edge 的 1/6 https://aws.amazon.com/blogs/aws/introducing-cloudfront-functions-run-your-code-at-the-edge-with-low-latency-at-any-scale/
文档中的示例function handler(event) {
var response = event.response;
var headers = response.headers;
// Set HTTP security headers
// Since JavaScript doesn't allow for hyphens in variable names, we use the dict["key"] notation
headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'};
headers['content-security-policy'] = { value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"};
headers['x-content-type-options'] = { value: 'nosniff'};
headers['x-frame-options'] = {value: 'DENY'};
headers['x-xss-protection'] = {value: '1; mode=block'};
// Return the response to viewers
return response;
}
如果您现在正在实施此功能,那么您很幸运。从 2021 年 11 月开始要简单得多。亚马逊通过响应 header 策略在本地添加了安全性 header,即我们不必创建 lambda 来仅向应用程序添加响应 header。 细节 https://aws.amazon.com/blogs/networking-and-content-delivery/amazon-cloudfront-introduces-response-headers-policies/.
Terraform AWS 提供商已从 3.64.0 开始支持 aws_cloudfront_response_headers_policy
https://github.com/hashicorp/terraform-provider-aws/blob/main/CHANGELOG.md#3640-november-04-2021.
这是一个通过 terraform aws 提供商向 aws 云端响应添加安全性 header 的示例。
resource "aws_cloudfront_response_headers_policy" "security_headers_policy" {
name = "my-security-headers-policy"
security_headers_config {
content_type_options {
override = true
}
frame_options {
frame_option = "DENY"
override = true
}
referrer_policy {
referrer_policy = "same-origin"
override = true
}
xss_protection {
mode_block = true
protection = true
override = true
}
strict_transport_security {
access_control_max_age_sec = "31536000"
include_subdomains = true
preload = true
override = true
}
content_security_policy {
content_security_policy = "frame-ancestors 'none'; default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"
override = true
}
}
}