我正在尝试在 ViewerResponse 事件上使用 Lambda@Edge 从 Cloudfront 响应中删除一些标头。来源是 S3 存储桶。
我已经成功地更改了标题,如下所示:
exports.handler = (event, context, callback) => {
const response = event.Records[0].cf.response;
response.headers.server = [{'key': 'server', 'value': 'bunny'}];
callback(null, response);
};
但是,一起删除标题似乎不起作用,例如像这样。
exports.handler = (event, context, callback) => {
const response = event.Records[0].cf.response;
delete response.headers.server;
// or response.header.server = null;
// or response.headers.server = [{'key': 'server', 'value': null}];
callback(null, response);
};
此代码片段不会删除,而是将服务器标头从
server: AmazonS3
更改为 server: CloudFront
。所以我假设服务器标头可能是强制性的并且会自动填充。但我也无法删除 CloudFront 生成的其他标头。在 lambda 测试窗格中,该函数按预期工作。所以 Lambda 函数完成后会发生一些事情。
作为背景,我想更改标头,因为该站点在重要客户端的网络中被阻止,并显示它是在线存储或备份位置的消息。
我错过了什么?
不幸的是,根据 AWS 支持,CloudFront 目前不支持此功能:
不可能完全删除服务器标头,我们可以将其设置为“无”,或者即使我们尝试完全删除服务器标头字段,CloudFront 也会在查看器响应中添加“Server:CloudFront”。
既然您提到了政府机构,您可能想问他们遵循什么政策。其中大多数可能基于 Apache 等事物的 CIS 基准,它们通常有一个“信息泄漏”目标,如下所示:
信息就是力量,识别 Web 服务器详细信息可以大大提高任何攻击的效率,因为安全漏洞极其依赖于特定的软件版本和配置。过多的探测和请求可能会导致生成过多的“噪音”,并可能向管理员举报。如果攻击者能够准确地定位其攻击目标,那么在检测之前成功入侵的机会就会大大增加。 Script Kiddies 不断扫描 Internet 并记录 Web 服务器公开提供的版本信息。此扫描的目的是积累这些主机上安装的软件的数据库,以便在发布新漏洞时使用。
我见过的推荐建议通常是除了删除它之外还允许使用 generic
Server
标头。例如,Apache 指南允许 Server: Apache
:
配置 Apache ServerTokens 指令以提供最少的信息。通过将该值设置为 Prod 或 ProductOnly。服务器 HTTP 响应标头中给出的唯一版本信息将是 Apache,而不是安装的模块和版本的详细信息。
如果您删除代码中的
Server
标头,CloudFront 添加自己的标头不会泄漏有关后端服务器的信息,也不会向攻击者提供新信息,因为他们已经知道自己正在连接到 CloudFront IP 地址。
我解决了! 您需要按照本文的步骤进行操作。这种方式专门在每个 Cloudfront 行为上实现的
Viewer Response
中使用 Lambda@Edge。
我用python解决了:
def lambda_handler(event, context):
headers = {'Content-Type': 'application/json'}
print(event)
response = event['Records'][0]['cf']['response']
response['headers']['server'] = [{"key": "Server", "value": "MyCustomServer"}]
print(response)
return response