chrome 更新跨域规则,将对网站造成影响
在 chrome v94 之后,之前没有问题的网站接口请求现在出现了错误:
Access to Css stylesheet at ‘http:xx’ from origin ‘http://xx‘ has been blocked by CORS policy: The request client is not a secure context and the resource is in more-prevate adddress space
local
看到 CORS
这个让人有种跨域既视感,那么问题来了,之前能跨域现在不能了?是 chrome 增加了新的跨域规则了吗?如果是,好家伙,奇怪的知识又增加了!
为什么更新此功能
它是根据专用网络访问规范所述并进行实现的, 目的是为了防止网站对本地服务进行攻击.
怎么理解呢?假设我本地内网环境有一个 http 服务,可能是为了方便都开启了跨域访问。例如直接访问 http://127.0.0.1:8080/images 即可获取大量个人实战总结的高清无码学习资料(你品,你细品)。然后我访问了某个不怀好意的在线网站,页面中类似代码:
// 获取本地资源并上传到服务器
fetch('http://127.0.0.1:8080/images').then((res) => {
res.arrayBuffer().then(buf=> {
// Upload data to the server....
// Upload data to the server....
// Upload data to the server....
})
});
让我们来看看哪些地址会受到此类攻击:
Address block | Name | Reference | Address space |
---|---|---|---|
127.0.0.0/8 | IPv4 Loopback | [RFC1122] | local |
10.0.0.0/8 | Private Use | [RFC1918] | private |
172.16.0.0/12 | Private Use | [RFC1918] | private |
192.168.0.0/16 | Private Use | [RFC1918] | private |
169.254.0.0/16 | Link Local | [RFC3927] | private |
::1/128 | IPv6 Loopback | [RFC4291] | local |
fc00::/7 | Unique Local | [RFC4193] | private |
fe80::/10 | Link-Local Unicast | [RFC4291] | private |
::ffff:0:0/96 | IPv4-mapped | [RFC4291] | see mapped IPv4 address |
以上这些都是 非公共 IP 地址块
,从公共页面请求私有服务的数据,或者从私有服务请求本地数据,都会触发上述错误。
由上图可知道,以下情况都是不允许的:
- 从公共服务访问私有服务
- 从公共服务访问本地服务
- 从私有服务访问本地服务
如何解决此问题
- 访问本地数据,即访问
http://localhost
(或http://127.*.*.*,
http://[::1]
) 则只需要把浏览的页面升级为 https 即可 - 访问私有IP,升级目标地址和访问的页面都为 https
- 从公共服务器(例如CDN)引用本地资源
- 在试验阶段, 可以设置 chrome 浏览器 chrome://flags/#block-insecure-private-network-requests 值为 disabled, 但这预计会在 chrome v101 失效
另外,chrome目前还没有完全实现规范中的所有内容。例如除了上面的解决方案,还可能可以使用 cors 预请求进行授权。
如果使用预请求的方式,那个我们只需要在 options 响应头中设置 Access-Control-Allow-Private-Network:true
即可, 这是一种较为简单的方案。
后记
有网友提到:
好像这个新协议也挡不住文中下载例子的情况? https的钓鱼网站还是有的…只要升级https协议就行…好像有点鸡肋?
这是个好想法,我首先思考是我的举例有问题还是是规范确实有点鸡肋,想了一会感觉例子也没什么毛病,规范应该也不会出现这么严重的漏洞。
然后我打算重新找找相关资料,看看规范中有如何处理 还是会受到攻击
这个问题的?
https 是方法跨站请求伪造(csrf)的基础
- HTTPS
HTTPS by itself does nothing to defend against CSRF. However, HTTPS should be considered a prerequisite for any preventative measures to be trustworthy.
HTTPS 本身并不能防御 CSRF。但是,HTTPS 应被视为任何值得信赖的预防措施的先决条件。
有同源策略来避免 csrf
- CORS
Fortunately, this request will not be executed by modern web browsers thanks to same-origin policy restrictions. This restriction is enabled by default unless the target web site explicitly opens up cross-origin requests from the attacker’s (or everyone’s) origin by using CORS with the following header:
Access-Control-Allow-Origin: *
- 幸运的是,由于同源策略 限制,现代网络浏览器不会执行此请求(诱骗受害者提交恶意请求)。默认情况下启用此限制,除非目标网站通过使用 带有以下标头的CORS明确打开来自攻击者(或每个人)来源的跨域请求:
Access-Control-Allow-Origin: *
私有网络规范
- 自己从预请求中决定是否允许访问
with the following implication: private network requests are only allowed if their client is a secure context and a CORS-preflight request to the target origin is successful.
- 当其客户端是
安全上下文
且对目标源的CORS 预检请求成功
时,才允许私有网络请求。这里的 安全上下文 可理解为不被浏览器的安全工具拦截,即认为是安全。预请求中还可以设置ip地址空间
来指定什么范围内的地址可以访问。
总结
所以回过头来看,谷歌浏览器确实是会首先禁止直接向私有地址进行访问(这一层由私有网络规范限制)。然后如果例子中的 api 本就开放了允许所有域名可以请求,那么自然就会受到跨站攻击(这一层由 CORS 规范限制)。