CORS policy-chrome v94 之后,将对旧系统造成的影响

595 阅读6分钟

名词

什么是专用网络

在互联网的地址架构中,专用网络是指遵守 RFC 1918(IPV4)和 RFC 4193(IPV6)规范,使用专用 IP 地址空间的网络。私有 IP 无法直接连接互联网,需要使用网络地址转换(Network Address Translator,NAT)或者代理服务器 (proxy server)来实现。
一般,我们在企业里搭建的局域网、家庭网络里的局域网、你本地的 localhost ,都属于专用网络。

什么是私有网络访问

Private Network Access(以前称为 CORS-RFC1918 )限制了网站向私有网络上的服务器发送请求的能力。根据规范,此类请求只允许来自安全上下文。另外,该规范扩展了跨域资源共享(CORS)协议,因此网站现在必须在允许发送任意请求之前,必须显式请求私有网络上服务器的许可。
私有网络是指目标服务器的IP地址比从其获取请求服务器的IP地址更私有的请求。例如,从公共网站(https://example.com)向私有网站(http://router.local)的请求,或从私有网站向 localhost 的请求。

Address blockNameReferenceAddress space
127.0.0.0/8IPv4 Loopback[RFC1122]local
10.0.0.0/8Private Use[RFC1918]private
172.16.0.0/12Private Use[RFC1918]private
192.168.0.0/16Private Use[RFC1918]private
169.254.0.0/16Link Local[RFC3927]private
::1/128IPv6 Loopback[RFC4291]local
fc00::/7Unique Local[RFC4193]private
fe80::/10Link-Local Unicast[RFC4291]private
::ffff:0:0/96IPv4-mapped[RFC4291]see mapped IPv4 address

以上这些都是 非公共 IP 地址块,从公共页面请求私有服务的数据,或者从私有服务请求本地数据,都会触发上述错误。

问题背景

老项目迁移过程中发现原有系统部分接口报跨域问题,但在fixfox,其他人的chrome上没这个问题。另外之前项目也是没问题的,之前能跨域现在不能了?
那排查发现出在chrome版本上。低版本chrome没问题,高版本chrome出现了问题。
参考链接:juejin.cn/post/702548…

has been blocked by CORS policy: The request client is not a secure context and the resource is in more-private address space `private`.

为什么会出现这个问题

chrome更新后,增加了专用网络访问规范 会限制网站向专用网络上的服务器发送请求的能力。它只允许来自安全上下文(HTTPS)的此类请求。该规范还扩展了跨域资源共享 (CORS) 协议,因此网站现在必须要经过专用网络上的服务器授权会才能发送请求

那项目中遇到的问题是

1、从39的公网IP http的请求,10开头的内网IP http的请求,出现的问题,那其实是符合从public-private,请求更私有的
2、那在localhost本地访问时,就没这个问题。那其实是从本地服务去访问私有的服务,是被允许的。
3、那这里在看一个其他人遇到的问题, 也是类似的问题,那其实场景都是内网使用的服务,那这里可以要求运维配置成的private情况
www.cnblogs.com/a14907/p/15…

该图下都会产生私有网络请求(目标服务器的 IP 地址比获取请求发起者的 IP 地址更私有的请求) image.png

那如何解决呢

访问 localhost

如果你的网站需要向 localhost 发出请求,那么你只需要将你的网站升级到 HTTPS。 混合内容不会阻止以 http://localhost(或 http://127.*.*.*、http://[::1])为目标的请求,即是从安全上下文发出的。

访问私有 IP

如果你的网站需要向私有 IP 地址上的目标服务器发出请求,那么简单地将发起方网站升级到 HTTPS是行不通的。混合内容会阻止安全上下文通过明文 HTTP 发出请求,因此新获得安全保护的网站仍会发现自己无法发出请求。将两端都升级为HTTPS可以解决这个问题:

CORS 预检请求

CORS 预检请求是一个 HTTP OPTIONS 请求,它带有一些 Access-Control-Request-* 标头,表明后续请求的性质,例如是否允许跨域访问。

专用网络访问规范 的第二部分是使用 CORS 预检请求 来控制从安全上下文发起的专用网络请求。即使请求是从安全上下文发起的,目标服务器也会被要求向发起者提供明确的授权,只有在授权成功时才会发送请求。

如果使用预请求的方式,只需要在 options 响应头中设置 Access-Control-Allow-Private-Network:true 即可。

设置chrome浏览器

在试验阶段, 可以设置 chrome 浏览器 chrome://flags/#block-insecure-private-network-requests 值为 disabled, 但这预计会在 chrome v101 失效

那总结以上,谷歌浏览器首先禁止直接向私有地址进行访问(这一层由私有网络规范限制)。然后如果开放了允许所有域名可以请求,那么自然就会受到跨站攻击(这一层由 CORS 规范限制)。

chrome v98的重大更新

Chrome 将在任何对子资源的私有网络请求之前开始发送 CORS 预检请求,该请求需要目标服务器的明确许可。 在 Chrome 98 这个版本,对私有网络的限制正式生效啦,主要目的是保护用户免受针对私有网络上的路由器和其他设备的 CSRF 攻击。攻击者可以借助这个攻击方式将他们重定向到恶意服务器。

预检请求 image.png

CORS 预检新增的两个 Header

为了限制私有网络请求,新增了两个 CORS 预检 Header

  • Access-Control-Request-Private-Network: true 在所有私有网络预检请求上设置
  • Access-Control-Allow-Private-Network: true 必须在所有私有网络预检响应上设置

注意:无论请求方法和模式如何,都会为所有私有网络请求发送预检请求。这个请求在 cors 模式以及 no-cors 所有其他模式中的请求之前就已经发送了。

如果目标 IP 地址比发起请求的网址更私密,私有网络的预检请求也会针对同源请求发送。这和我们理解的常规 CORS 不一样,其中预检请求只会用于跨域请求。同源请求的预检请求还可防止 DNS 重新绑定攻击。

详细内容见: