【发布时间】:2017-01-10 16:36:00
【问题描述】:
我在静态文件(js、css、jpg、gif、.. .) 在我的 Amazon S3 存储桶上。
当我尝试添加它时,它告诉我:“用户定义的元数据键必须以 x-amz-meta- 开头。”
如何做到这一点?我应该做“x-amz-meta-X-Content-Type-Options”
提前致谢!
【问题讨论】:
标签: security amazon-s3 header mime-types
我在静态文件(js、css、jpg、gif、.. .) 在我的 Amazon S3 存储桶上。
当我尝试添加它时,它告诉我:“用户定义的元数据键必须以 x-amz-meta- 开头。”
如何做到这一点?我应该做“x-amz-meta-X-Content-Type-Options”
提前致谢!
【问题讨论】:
标签: security amazon-s3 header mime-types
用户定义的元数据确实必须以 x-amz-meta-* 开头,但这对您没有帮助 - 当获取对象时,它们也返回为 x-amz-meta-* 标头,x-amz-meta-X-Content-Type-Options 将浏览器无法识别。
S3 对不以 x-amz-meta-* 开头的标头的支持非常有限。 Content-Type 和 Content-Disposition 和 Content-Encoding 有效,但其他大多数无效。
正如this support forum post 指示(并通过测试确认)如果将此类标头添加到上传(直接使用 S3 API 时),它们会被简单地忽略。它们不会被存储,也不会随响应返回。
一个已知但未记录的异常是 X-Robots-Tag,S3 接受并返回响应,但如果您使用 API 添加它,AWS 控制台将不允许您对其进行编辑。
一种可能即将推出的解决方法是Lambda@Edge,它是 Lambda 和 CloudFront 之间的集成,其中 Lambda 函数在 CloudFront 网络中运行,并且可以修改进出 CloudFront 的请求和响应标头...当然,CloudFront 与 S3 集成得很好,因此一旦 Lambda@Edge 普遍可用,这可能是一个可行的选择。
我对此进行了测试(我注册了 Lambda@Edge 的预览版。我还没有正式收到我已获得访问权限的回复,但它似乎正在工作。)
使用这个 Lambda 函数代码:
'use strict';
exports.handler = (event, context, callback) => {
const response = event.Records[0].cf.response;
const headers = response.headers;
headers['X-Content-Type-Options'] = ['nosniff'];
callback(null, response);
};
...给出这个响应...
$ curl -v http://dxxxexample.cloudfront.net/robots.txt
* Hostname was NOT found in DNS cache
* Trying x.x.x.x...
* Connected to dxxxexample.cloudfront.net (x.x.x.x) port 80 (#0)
> GET /robots.txt HTTP/1.1
> User-Agent: curl/7.35.0
> Host: dxxxexample.cloudfront.net
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/plain
< Content-Length: 324
< Connection: keep-alive
< Date: Tue, 10 Jan 2017 20:38:33 GMT
< Last-Modified: Tue, 10 Jan 2017 17:13:36 GMT
< ETag: "dbe2f9a267e8ef192f0fdf0c888da01c"
< Cache-Control: no-cache
< Accept-Ranges: bytes
* Server AmazonS3 is not blacklisted
< Server: AmazonS3
< Via: 1.1 xxxxxxxxxx.cloudfront.net (CloudFront)
< X-Content-Type-Options: nosniff
< X-Cache: Miss from cloudfront
< X-Amz-Cf-Id: xxxxx
<
User-agent: *
Disallow: /
...所以这似乎是一个可行的解决方法。
我将此函数配置为在“查看器响应”上触发(触发器触发以允许在响应从 CloudFront 返回到浏览器之前修改响应)但实际上它可能会在“原始响应”上触发,需要它减少运行频率(假设,与上面的示例不同,您没有像我在测试中那样使用Cache-Control: no-cache。我使用/robots.txt 只是因为我碰巧已经在桶中设置了这个CloudFront 和 Lambda —— 显然,这个文件对于 X-Content-Type-Options 来说并不是一个特别有趣的应用程序,但正如您所见,它确实有效)。
我不知道 Lambda@Edge 什么时候会从预览版中发布。
如果您想将此作为 S3 本身的功能请求提交,您可以联系您的 AWS 客户代表(如果有的话),或者在 AWS 支持论坛中发布相关信息。 (我不隶属于 AWS)。
【讨论】: