Chrome
正在计划禁止从非安全网站发起的私有网络请求,目的是保护用户免受针对专用网络上的路由器和其他设备的跨站点请求伪造 (CSRF
) 攻击。
私有网络请求是其目标服务器的 IP 地址比获取请求发起者的 IP 地址更私有的请求。例如,从公共网站 ( https://example.com) 到私有网站 (http://router.local) 的请求,或从私有网站到 localhost 的请求。
自 Chrome 94
版本,开始阻止来自不安全上下文(非 HTTPS
协议)的公共网站的私有网络请求。
详细的策略更新可以看我之前写的这篇文章:Chrome 重大更新,将限制 localhost 访问?
但是这项更新却给广大开发者的本地开发和调试带来了很大的困扰,从私有设备(比如我们自己的本地调试环境)移到 HTTPS
协议还是挺困难的。
所以此项更新开始后,很多测试或者预发环境都开始报错,其实正是因为我们在这些环境中数据不安全的上下文(非 HTTPS
协议),但是却发起了私有网络请求(比如从测试环境发到本地调试服务器的请求)。
正是为了解决这个问题,Chrome 120
版本推出了一项新的权限提示。
首先,我们可以在发起 fetch
请求的 Options
选项中添加 targetAddressSpace
,就可以跳过上面提到的混合内容的检查。
fetch("http://router.localhost/conardli", {
targetAddressSpace: "private",
});
注意:在混合内容检查中,本身像
http://localhost
、127.0.0.0/8
和::1/128
这样的本地 IP 地址被认为是潜在可信的,所以在这些情况下不需要添加targetAddressSpace
也是可以请求成功的。
根据私有网络访问策略的限制,任何私有网络请求发起之前都会先发起预检请求。
具体可以看我之前写的这篇文章:Chrome 安全策略 - 私有网络控制(CORS-RFC1918)
预检请求会包含一个新的 Request Header
: Access-Control-Request-Private-Network: true
。并且相应的响应也必须包含一个 Response Header
:Access-Control-Allow-Private-Network: true
。
为了适应新的权限提示,此次更新又引入了两个新的 Response Header
,而且是要求必须添加的:
Private-Network-Access-Name
:一个可读的名称标识(与 ECMAScript
正则表达式 /^[a-z0-9_-.]+$/
匹配的有效名称字符串,名称的最大长度为 248
个 UTF-8
代码单元。)Private-Network-Access-ID
:设备的 MAC 地址(48 位值,以冒号分隔的 6 个十六进制字节表示)例子:
Private-Network-Access-Name: "ConardLi Computer"
Private-Network-Access-ID: "17:17:17:17:17:0A"
注意:当私有网络权限提示绕过混合内容检查时,即使在预检警告模式下,也会强制执行预检。
可以在下面这个网址查看具体的 Demo 演示:https ://private-network-access-permission-test.glitch.me/