名词
什么是专用网络
在互联网的地址架构中,专用网络是指遵守 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 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 地址块,从公共页面请求私有服务的数据,或者从私有服务请求本地数据,都会触发上述错误。
问题背景
老项目迁移过程中发现原有系统部分接口报跨域问题,但在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 地址更私有的请求)
那如何解决呢
访问 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攻击。攻击者可以借助这个攻击方式将他们重定向到恶意服务器。
预检请求
CORS 预检新增的两个 Header
为了限制私有网络请求,新增了两个 CORS 预检 Header
Access-Control-Request-Private-Network: true在所有私有网络预检请求上设置Access-Control-Allow-Private-Network: true必须在所有私有网络预检响应上设置
注意:无论请求方法和模式如何,都会为所有私有网络请求发送预检请求。这个请求在
cors模式以及no-cors所有其他模式中的请求之前就已经发送了。
如果目标 IP 地址比发起请求的网址更私密,私有网络的预检请求也会针对同源请求发送。这和我们理解的常规 CORS 不一样,其中预检请求只会用于跨域请求。同源请求的预检请求还可防止 DNS 重新绑定攻击。
详细内容见:
- chrome 私有网络访问的文章 developer.chrome.com/blog/privat…
- cloud.tencent.com/developer/a…