如何在 Web 应用程序前端强制 fetch 接受自签名证书?

Gra*_*tty 7 javascript https fetch

我正在制作一个简单的 Web 应用程序前端原型,它需要从我的服务器获取 JSON 数据。服务器本身工作正常——我可以单击链接,JSON 数据就会显示在浏览器中。但以下简单脚本失败了:

    fetch('https://x.x.x.x:8000')   //  MY URL FAILS
    // fetch('https://jsonplaceholder.typicode.com/todos/1')  // ALTERNATE URL WORKS
    .then(function() {
        alert("Successful")
    })
    .catch(function() {
        alert("Failure")
    }); 
Run Code Online (Sandbox Code Playgroud)

我对这种前端工作(以及一般的 Javascript)完全陌生,所以我可能会忽略一个明显的原因,但我想到的两个是

  1. 我的服务器使用自签名证书进行测试;和/或
  2. 我使用的是非标准端口。

这些可能的解释中的第一个似乎更有可能。

访问网页会产生一堆错误,这些错误对我来说没有任何意义(除了找不到图标):

在此输入图像描述

我会暂时在下面的评论中发布完整的 URL,以防其他人想看看会发生什么,但一旦提出可行的解决方案,我就会将其删除。

lxh*_*hom 7

刚刚遇到了同样的问题,偶然发现了解决方案。只需让用户打开自签名网站,单击“显示更多”和“接受风险并继续”即可。完成此操作后,fetch请求就会顺利进行,就像没有出现任何问题一样。

它适用于火狐浏览器:

在此输入图像描述

和铬:

在此输入图像描述

此方法只是警告您必须进行设置,并且在 Chrome 上,即使页面的其余部分是安全的,它也会显示“不安全”。

在此输入图像描述

但如果您在本地需要 HTTPS,这就像一个魅力。希望这对从 Google 来到这里的人有所帮助:)

编辑:

另外值得一提的是,我在本地主机上测试了它,但它在任何地方都可以工作。

在此输入图像描述


CBH*_*ing 5

要回答您提出的问题,不,您绝对不能用来fetch强制客户端(浏览器)忽略证书错误。特别是在跨源请求中(从一个端口到另一个端口就是跨源),这将是一个巨大的请求安全漏洞。任何能够在受害者网络上获得中间人位置的人(并不难)都可以使用欺诈性证书从受害者的 HTTPS 连接中窃取信息,以拦截 HTTPS 请求和响应。

您也许能够强制服务器端 JS(在 Node 或类似中)忽略证书验证错误,因为在这种情况下您(希望如此!)控制服务器正在运行的代码。但看起来这并不是您正在做的事情,并且在网页中,其他人(服务器所有者)控制您(浏览器)正在运行的代码,因此您绝对不能让该代码关闭重要的安全功能!


JS 可以关闭证书验证的攻击场景:

假设你和我都控制网络服务器。我,一个恶意攻击者,想要拦截您的用户和您的网络服务器之间的流量。我什至对您的一些用户拥有中间人 (MitM) 网络位置!但是,您当然使用 TLS(通过 HTTPS),因此我无法解密或修改流量。

但是,您的用户有时也会连接到我的服务器,而不知道它是恶意的(也许我主要使用它来提供相对无害的东西,例如评论系统或分析工具,因此很多网站都嵌入了我的脚本)。我的服务器可以判断浏览器何时从 IP 地址请求内容,我可以在其中发起 MitM 攻击,并向其提供恶意脚本。

现在,在现实世界中,这并不重要!由于同源策略(一项重要的浏览器安全功能) ,站点不信任其他站点。我的网站(或我提供的脚本)可能会导致您的用户向我选择的任何其他服务器提交请求,但他们无法读取响应(如果其他服务器是跨源的),并且他们无法关闭证书验证,所以我的 MitM 职位几乎毫无用处。

但是,假设有一种方法(正如您所建议的那样)让脚本告诉浏览器“没关系,在发出此请求时只需信任这个特定的自签名证书”。这改变了一切。我的 MitM 主机将为您的站点生成自签名证书(以及相应的私钥),并将该证书发送到我自己的 Web 服务器。当潜在受害者加载我的脚本时,它仅包含向您的站点发出 HTTP 请求的指令,它还指定浏览器应信任我的 MitM 节点生成的自签名证书。

然后,受害者的浏览器将启动请求,尝试与您的服务器建立 TLS 连接。我的 MitM 节点将拦截该请求,并用其自签名证书进行回复。通常浏览器会拒绝,但在这种情况下不会,因为您创建了一种方法来告诉浏览器接受特定的自签名证书。因此,受害者的浏览器信任我的自签名证书。实际的请求甚至从未到达您的服务器。受害者的浏览器认为自己正在与合法服务器(您的)而不是与我的 MitM 主机进行交互,因此会发送包含 cookie 和/或 API 密钥/不记名令牌/登录凭据/等机密的 HTTP 请求。我的 MitM 会拦截该请求(因为它拦截所有流量)、解密(因为它实际上是 TLS 隧道的一端,这很简单),并且可以访问您服务器上的受害者帐户。(我的 MitM 主机还可以复制受害者通常会看到的来自服务器的响应,以使他们毫无戒心。如果我希望它误导用户, MitM 主机甚至可以篡改此响应。)


解决此问题的常用方法是将服务器的证书安装为浏览器(或操作系统)中受信任的证书。这样,浏览器就会将证书的颁发者(本身)识别为有效的,并认为该证书有效。

如果您访问https://xxxx:8000/会发生什么如果直接在浏览器中如果您收到证书错误,那么这就是您的问题:浏览器不信任该端口上托管的服务器的证书。您应该有机会暂时或永久信任该证书(具体细节取决于浏览器)。

当然,请注意,在您自己的计算机上执行此操作并不能解决其他人的计算机上的问题。他们也需要手动信任您的证书。


实际的解决方案当然是安装受信任的证书。也许您应该尝试 Let's Encrypt 或类似的工具,以获得每个客户都会信任的免费证书,而无需额外的恶作剧?