WebP Cloud 目前已支持在图片 CDN 上设置回源 UA, CORS Header 并支持限制 Referer
在之前的文章中,我们对比了一些和我们有类似功能的图片 CDN,发现除了直接将 NS 记录给转移到 CDN 服务商的(以 Cloudflare 为典型)以外,基本都会根据源站的图片地址给你一个新的地址,这一点上 WebP Cloud 也不例外。
具体来说,假设你的图片地址在:
https://blog.example.com/some/cat.jpg
那么一般来说你会获得类似如下的新地址:
# WebP Cloud
https://e52565b.webp.ee/some/cat.jpg
# Vercel
https://cdn-image.example.com/_next/image?url=https://blog.example.com/some/cat.jpg?w=640&q=75
# Other CDN
https://cdn.example.com/some/cat.jpg
要「接入」CDN 的话只需要将对应的图片地址换成新的地址即可。
这样做本身其实没有什么问题,使用一个新的地址可以在保证源地址可用的情况下减少接入成本,但是这里就有被盗链和 CDN 穿透(绕过)的风险,我们考虑以下两个场景:
- CDN 上可能会配置一些规则,比如生成水印(WebP Cloud 支持)防止原图被直接下载
- 源站可能是直接放在 AWS S3 这种流量费比较贵的服务上,使用 CDN 的目的主要是为了缓存减少 Egress 流量费用
- 其他网站,例如
https://some-content-farm.com
可以直接使用img
标签来使用你的 CDN 地址的图片,产生额外的 CDN 请求数量/流量费用
我们对于上面的场景一个个来看:
- 假设我们的图片
https://e52565b.webp.ee/some/cat.jpg
是放在https://blog.example.com
页面上的,一个访客想下载对应的原图(因为博客上的图片可能加入了水印之类的不希望原图被直接拿走),可以很自然的猜到原图地址就是https://blog.example.com/some/cat.jpg
,这个时候没有水印的原图就被盗走了,我们认为 CDN 被穿透(绕过)了 - 对于后面两个情况其实也是如此,Vercel 甚至直接把原图地址就放在 URL 的 Params 上,访客可以很容易拿到原图
对于一般情况而言,可能 CDN 被穿透无非是多点源站流量费用的问题,但是如果你使用 CDN,并设置了水印就是为了防止图片被恶意盗用的话,那这里就有潜在的风险点了。
对于以上问题,我们最近发布的新功能打算从三个维度来尝试解决。
回源 UA
对于一般的 CDN 而言,访客使用的 User Agent 在 CDN 回源的时候会被直接发送给源站,WebP Cloud 和传统 CDN 在这个地方有一些差异。
WebP Cloud 目前回源用的 UA 是固定的字符串: WebP Cloud Services/1.0
,用户请求的流程如下:
访客对
https://e52565b.webp.ee/some/cat.jpg
发起请求,请求的 Header 如下:
- User-Agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
- User-Agent:
假设对应图片并没有在 WebP Cloud 上缓存,需要回源,WebP Cloud 接受到请求之后向源站
https://blog.example.com/some/cat.jpg
发起 GET 请求,请求的 Header 如下:
- User-Agent:
WebP Cloud Services/1.0
- User-Agent:
WebP Cloud 拿到了原始图片之后进行对应的处理,并返回给访客
这里,我们的新功能允许用户设置回源时的 User-Agent ,即现在默认为 WebP Cloud Services/1.0
的字段,例如用户可以设置为: User-557f51ce-Custom
,这样这里 User Agent 可以作为一个 Pre-shared Key 的形式用于保证源站地址只能被 WebP Cloud 访问,杜绝了源站地址被猜到而导致 CDN 穿透(绕过)的问题。
设置了自定义的 User Agent 之后,源站可以用如下类似的配置来保证图片请求仅允许 WebP Cloud 回源:
Nginx
server {
listen 80;
server_name blog.example.com;
location ~ \\.(jpg|jpeg|png|gif)$ {
if ($http_user_agent !~ "User-557f51ce-Custom") {
return 403;
}
}
location / {
# 其他配置
}
}
Cloudflare
(http.user_agent ne "User-557f51ce-Custom") and ((http.request.uri.path contains "jpg") or (http.request.uri.path contains "png") or (http.request.uri.path contains "jpeg") or (http.request.uri.path contains "gif"))
AWS S3
可以通过编写 Bucket Policy 的方式来限定访问 UserAgent,例如:
{
"Version": "2012-10-17",
"Id": "OnlyAllowWebPCloud",
"Statement": [
{
"Sid": "AllowSpecificUserAgent",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::blog-webp-se/*",
"Condition": {
"StringEquals": {
"aws:UserAgent": "User-557f51ce-Custom"
}
}
},
{
"Sid": "DenyOthers",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::blog-webp-se/*"
}
]
}
CORS Header
为了减少图片在站外被其他网站直接引用,我们允许用户设置自己的 CORS Header,可以在 Dashboard 上设置,这个默认值是 *
,表示允许所有网站使用,在上面的例子中,如果你希望 https://e52565b.webp.ee/some/cat.jpg
只被博客域名 https://blog.webp.se
使用的话,可以设置为 blog.webp.se
,这样设置之后所有的请求返回的 Header 中的 Access-Control-Allow-Origin
字段会被设置为 blog.webp.se
,对于其他网站的引用来说,图片会无法直接正常显示(提示 CORS 错误),进一步减少被盗链的风险。
Allowed Referer
- 需要注意的是 referer 实际上是 “referrer” 误拼写。参见 HTTP referer on Wikipedia(HTTP referer 在维基百科上的条目)来获取更详细的信息。
上文中设置 CORS Header 的方式可以有效防止其他网站的前端框架引用你的图片,但是如果其他网站直接使用 img
标签使用图片的话,也就没有办法了。
所以这里我们提供一层额外的限制,通过限制网站的 referer
字段来进一步减少图片被盗用的概率。
- Referer 请求头包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的。服务端一般使用 referer 请求头识别访问来源,可能会以此进行统计分析、日志记录以及缓存优化等。
例如用户在访问: https://wordpress.webp.se/ 的时候,浏览器在加载页面上的图片时会带上:
Referer: https://wordpress.webp.se/
这个请求头,用来向服务端告知目前是哪个页面引用了这个图片,WebP Cloud 最近的新功能让用户可以在后台设置允许的 referer
,默认是 *
表示允许任意 referer
,如果你希望对此加以限制的话,可以用逗号分割的域名的形式,比如 wordpress.webp.se,nova.moe,dmesg.app,tuki.moe
,假设这个时候有其他域名尝试直接用 img
标签的方式嵌入图片的话,WebP Cloud 会返回 403 阻止图片显示:
当然,防止图片被盗链有很多需要做的事情,以上只是 WebP Cloud 在保护源站安全和图片防盗链上做的一些微小的贡献。
和往常我们添加的新功能一样,WebP Cloud 一直坚信所有用户应该获得同等的使用权利。因此无论你是付费用户还是免费用户,以上三个功能均可随意使用。
WebP Cloud Services 团队是一个来自上海和赫尔辛堡的三人小团队,由于我们不融资,且没有盈利压力 ,所以我们会坚持做我们认为正确的事情,力求在我们的资源和能力允许范围内尽量把事情做到最好, 同时也会在不影响对外提供的服务的情况下整更多的活,并在我们产品上实践各种新奇的东西。
如果你觉得我们的这个服务有意思或者对我们服务感兴趣,欢迎登录 WebP Cloud Dashboard 来体验,如果你好奇它还有哪些神奇的功能,可以来看看我们的文档 WebP Cloud Services Docs,希望大家玩的开心~
Discuss on Hacker News