0%

专用网络的 CORS (RFC1918) 问题研究及解决方案

问题

场景

时间:2021年11月22日

页面:http://xxx.xxx.xx/tools/xxxxx

接口:http://10.1.xxx.xxx:8080/api/xxxx

浏览器:Chrome 92+

错误信息

错误截图:

错误提示:

Ensure private network requests are made from secure contexts

A site requested a resource from a network that it could only access because of its users’ privileged network position. These requests expose devices and servers to the internet, increasing the risk of a cross-site request forgery (CSRF) attack, and/or information leakage.
To mitigate these risks, Chrome deprecates requests to non-public subresources when initiated from non-secure contexts, and will start blocking them in Chrome 92 (July 2021).
To fix this issue, migrate the website that needs to access local resources to HTTPS. If the target resource is not served on localhost, it must also be served on HTTPS to avoid mixed-content issues.
Administrators can make use of the InsecurePrivateNetworkRequestsAllowed and InsecurePrivateNetworkRequestsAllowedForUrls enterprise policies to temporarily disable this restriction on all or certain websites.

错误关键词:专用网络的 CORS (RFC1918)

相关资料:https://developer.chrome.com/blog/private-network-access-update/#register-deprecation-trial

问题排查及分析

问题触发时段

在非Chrome浏览器下,如QQ浏览器,360浏览器,可以正常访问,无此跨域问题。

控制台打印QQ浏览器内核,输出结果如下,是 Chrome/70.0.3538.25 版本内核

1
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3872.400 QQBrowser/10.8.4455.400"

在Chrome浏览器下,查看内核信息,输出结果如下,为 Chrome/95.0.4638.69

1
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'

在上方的错误提示中,提及

To mitigate these risks, Chrome deprecates requests to non-public subresources when initiated from non-secure contexts, and will start blocking them in Chrome 92 (July 2021).

从2021年7月起,chrome内核为92版本之后的谷歌浏览器,都会受到影响并触发此错误

以下为相关资料译文

  • 2021 年 4 月:Chrome 90 推出稳定版,出现弃用警告。
  • 2021 年 6 月:Chrome 92 推出 Beta 版,禁止来自不安全环境的私有网络请求。在开发人员反馈要求更多时间进行调整后,弃用被推迟到 Chrome 93,并伴随着弃用试用。
  • 2021 年 7 月:经过开发者的进一步反馈,弃用和随附的试用版将推迟到 Chrome 94。此外,私人网站不再受弃用的影响。
  • 2021 年 8 月:Chrome 94 推出 Beta 版。Web 开发人员可以开始注册弃用试用版。
  • 2021 年 9 月:Chrome 94 推出稳定版。Web 开发人员应该已注册弃用试用并将试用令牌部署到生产中。
  • 2022 年 4 月:Chrome 102 推出 Beta 版。

官方说明及建议

Private Network Access

Private Network Access (formerly known as CORS-RFC1918) restricts the ability of websites to send requests to servers on private networks. It allows such requests only from secure contexts. The specification also extends the Cross-Origin Resource Sharing (CORS) protocol so that websites now have to explicitly request a grant from servers on private networks before being allowed to send arbitrary requests.

Private network requests are requests whose target server’s IP address is more private than that from which the request initiator was fetched. For example, a request from a public website (https://example.com) to a private website (http://router.local), or a request from a private website to localhost.

译文

专用网络访问(以前称为 CORS-RFC1918)限制网站向专用网络上的服务器发送请求的能力。它只允许来自安全上下文的此类请求。该规范还扩展了跨域资源共享 (CORS) 协议,因此网站现在必须在允许发送任意请求之前明确请求专用网络上的服务器的授权。

私有网络请求是其目标服务器的 IP 地址比获取请求发起者的 IP 地址更私有的请求。例如,从公共网站 ( https://example.com) 到私有网站 ( http://router.local) 的请求,或从私有网站到 localhost 的请求。

解决方法:

To fix this issue, migrate the website that needs to access local resources to HTTPS. If the target resource is not served on localhost, it must also be served on HTTPS to avoid mixed-content issues.

为了解决这个问题,将需要访问本地资源的网站迁移到HTTPS。如果目标资源不是在localhost上提供,也必须在HTTPS上提供,以避免混合内容问题。

验证

私有网络Web端(http://10.1.17.xxx:3000)访问私有网络Server端(http://10.1.17.xxx:8080/),可以正常请求:

  • 本地搭建 web 服务,地址为 http://10.1.xx.xxx:3000/,页面会调用接口 http://10.1.xx.xxx:8080/ 获取返回值。
  • 本地搭建 server 服务,地址为 http://10.1.xx.xxx:8080/,接口类型 Get ,返回值Hello!

公有网络Web端(http://test.xxxxx.com)访问私有网络Server端(http://10.1.17.xxx:8080/),产生报错:

  • 服务器端搭建 web 服务,地址为 http://test.xxxxx.com/,页面会调用接口 http://10.1.xx.xxx:8080/ 获取返回值。
  • 本地搭建 server 服务,地址为 http://10.1.xx.xxx:8080/,接口类型 Get ,返回值Hello!

公有网络Web端(http://test.xxxxx.com)访问公有网络Server端(http://119.xx.xx.xx:9091),可以正常请求:

  • 服务器端搭建 web 服务,地址为 http://test.xxxxx.com/,页面会调用接口 http://119.xx.xx.xx:9091/ 获取返回值。
  • 本地搭建 server 服务,地址为 http://10.1.xx.xxx:8080/,接口类型 Get ,返回值Hello!
  • 本地与服务器端搭建了内网穿透服务 由 http://10.1.xx.xxx:8080/ 转发至 http://119.xx.xx.xx:9091/

结论

见图专用网络访问 (CORS-RFC1918) 中公共、专用、本地网络之间的关系。

Chrome 为了保证避免防止网站对本地服务进行攻击,做了此措施

举例 www.xxxx.com 页面可能会有以下恶意逻辑

  • 遍历请求内网地址 localhost 127.0.0.1 10.x.x.x 172.x.x.x

    内网网段说明
    内网地址分为A,B和C类
    以下这些地址都属于内网
    A类地址范围:10.0.0.0 - 10.255.255.255
    B类地址范围:172.16.0.0 - 172.31.255.255
    C类地址范围:192.168.0.0 - 192.168.255.255
    除了以上的地址和一些比较特殊的地址如127.0.0.1, 169.254.0.0/16等,其他的都属于公网地址

  • 获取到返回信息后,将信息通过接口上传到自己的服务器

从而恶意获取了公司内网才能访问的数据

问题触发原因

  • Web页面为 http://test.xxxx.cn - 公网
  • 接口地址为 http://172.xx.xx.xxx:8080 - 内网
  • Chrome 版本号 92+ - 大于92版本

公网不能访问内网的内容,所以会在高于92版本浏览器中会产生报错,浏览器内核低于92版本则不会报错

问题解决方案

解决方法比较灵活:

  1. 开发及测试时应该用内网页面访问内网接口
  2. 上线时应该使用公网接口访问公网接口
  3. 如果需要公网访问内网数据,则需要做内网穿透转发后端数据

参考链接