这是什么?
只是随便搜集的一些头像接口,全部来自于我手机里目前安装的大部分APP服务。其中无 Web 标识的头像,如果你能看得见,那么证明该服务商并没有做严格的SSL校验,导致逆向极其简单。无该标识的默认为移动APP。以下所有资源均来自我个人使用的账号
一些小发现
- 微软(Microsoft)的头像非常严格,使用Cookie校验,不能直接访问
- 微信、支付宝,TapTap,钉钉不采用Web协议,故抓不到包
- 小黑盒,网易云音乐,酷安,作业帮,豆包,肯德基,库街区都采用了严格的SSL校验,不能直接访问
- 下述图片,除了TapTap校验Referer,其他都没有校验Referer,故可以直接访问。不过就算校验Referer也是徒劳
| 头像 | 描述 |
|---|---|
| OPPO(Web) | |
| Google(Web) | |
| 小米(Web) | |
![]() | 京东(Web) |
| 高德地图(Web) | |
| 美团 | |
![]() | 淘宝 |
| 拼多多 | |
| GitHub(Web) | |
![]() | Telegram(Web) |
| WPS(Web) | |
![]() | 闲鱼 |
| 好游快爆 | |
![]() | 网易云音乐(Web) |
| KOOK | |
| TapTap(Web) | |
| (微信)公众号助手 | |
![]() | 百度网盘 |
| Steam(Web) |
这表明了什么?
对于图片,音乐,影片等静态资源,若直接使用 img audio video 等标签,无需CORS即可将远端资源在任意网页上展示。这是W3C规范的一部分,详情请参考 HTML5 嵌入内容
当然,如果您是一个网站的维护者,您可能不想让陌生人直接将你的资源展示给别人看,或者怕被刷出账单,下面我将简单说明哪些措施是有效的,哪些是掩耳盗铃
首先我们来分辨一下您手动做服务端的防盗链和浏览器CORS的区别:
浏览器CORS是客户端行为,当某个行为被对端CORS策略拒绝,浏览器会阻止响应体。而服务端防盗链是在您的后端上编写一些小脚本,用以拒绝非法访问。前者会在用户浏览器弹出CORS错误,而后者会在用户浏览器显示错误状态码,如500,401,403,这取决于您的实现
是否可以尝试设置Referer白名单来拒绝非法访问? 没用 因为Referer在浏览器中是可以伪造或者不发送的。详见 HTML 5 引用来源策略
您应该做的事情稍微有些复杂,如将API放到Cookie(登录,非游客权限)中,并且让后端处理Cookie的发放与吊销。就像微软那样
又或者说,您只想要用户仅能通过浏览器单独查看图片,而不让 任何人(包括您) 引用图片到网站中,您可以使用 Accept 请求头 白名单,您可以尝试比较一下这两个 Accept 请求头 ,前者是直接访问图片浏览器自动发送的,而后者是引用时发送的
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8最后,如果您想做到图片必须是 游客访问 ,又不想让他人滥用。可以使用CORP(Cross-Origin-Resource-Policy)
只需要在别人拉取图片时返回一个CORP响应头,如: Cross-Origin-Resource-Policy: same-origin
另外,CORP不仅能保护图片,它可以保护一切东西,下面是一个简单的示意图 浏览器拉取资源 -> 请求资源,检查响应头 -> CORP(给不给用,默认给用) -> CORS(给不给JS读,默认不给) -> 返回
当CORP响应头返回的策略中和将要拉取资源的源不匹配,浏览器会阻止资源在页面加载,但并不会阻断原始请求
| 值 | 描述 |
|---|---|
| same-origin | 同源。仅允许 example.com 拉取对应资源 |
| same-site | 同站。仅允许 *.example.com example.com 拉取资源 |
| cross-origin | 默认值。允许所有源,任何人都可以拉取 |
设置后跨站引用会被浏览器阻止
- Chromium(Edge/Chrome)
另外提一嘴,Chromium 最近推了一个更新,导致CORS/CORP错误默认不显示在控制台,需要勾选 显示控制台中的CORS错误 控制台功能参考 | Chrome DevTools | Chrome for Developers
- Firefox

发现错误或想要改进这篇文章?
在 GitHub 上编辑此页





