Javascript/Flash 可以验证 SSL 连接以防止“SSL 检查”吗?

信息安全 应用安全 tls 证书 闪光 银光
2021-09-01 05:21:46

我想确定是否正在通过Fiddler调试 SSL 网页,或者是否正在通过SSL Proxy

所以有人可能会问

使用 javascript 重新验证 SSL 有什么意义?

我的目标是知道连接何时受到答案中提到的第 3 方拦截。漏洞是密码可能会暴露,用户会话也会暴露。当恶意软件或公司 IT 政策规定 SSL 拦截和监控时,所有这些都是可能的。

如果 SSL 连接被拦截怎么办?

根据应用程序的敏感性,如果正在使用双因素身份验证,我可能会以编程方式阻止连接或限制对网站某些部分的访问。我还可以放置横幅通知,说明使用该信息亭的安全风险。...或者我可以允许用户添加“例外”,前提是他们了解风险。

我的问题

Javascript 可以检查当前 SSL 证书的详细信息,包括 CA 链吗?

我认为解决这个问题的正确方法是查看证书的颁发者,并查看证书链的其余部分。下一步将列出链中的每个证书,并查看这些 CA 是否与公开信任的根 CA 相同。我想明确排除用户可能已将自己添加到本地计算机的其他证书。

我希望 security.stackexchange.com 上的人们能够提供有关如何解决此问题的想法。

如果 Javascript 无法验证当前的 SSL 连接,有什么替代方案?

由于这在纯 JavaScript 解决方案中可能或不可能,我用 Flash 标记了这个问题,因为它应该能够完成此操作,并将响应发送回 Javascript。

如果有人有 Java ME 经验,请说明这是否可能。任何其他广泛部署的插件也是如此。

相关技术的源代码表示赞赏。

4个回答

你问了替代方案。坦率地说,这是一个棘手的问题:如果有人在您的 SSL 会话中扮演中间人,而用户没有注意到或允许它继续进行,那么您将处于一个非常艰难的境地。但是,如果 Javascript 无法检查服务器在此 HTTPS 连接上提供的证书,我将尝试集思广益,您可以考虑一些替代方案。这两个想法充其量都远非完美,但我会将它们传递给他们以防万一。

想法1.不要相信浏览器。一种可能的替代方法是使用双因素身份验证和确认,这样您就不会 100% 依赖浏览器会话。例如,对于在线银行应用程序,如果用户执行了敏感操作,服务器可以向用户的手机发送一条短信,列出交易信息(“向 AT&T 支付 100 美元?批准,输入此 PIN:2781”),然后要求用户在他们的同意下做出回应或在他们的浏览器会话中输入 PIN。但是,我意识到这对用户来说很烦人且不方便。

想法 2. 原始套接字。您可以探索的另一种可能性:使用 Flash 或 Java 打开到服务器上某个 TCP 端口的原始套接字。如果这没有被代理拦截/中间人,您现在有许多选项来检测代理。一种简单的检测策略:如果服务器注意到与原始套接字关联的源 IP 地址与与此 HTTPS 连接关联的源 IP 地址不同。(但是这可能会产生误报......)您也可以通过使用浏览器识别但代理不拦截的其他协议处理程序来绕过没有 Flash 或 Java 的代理,例如 ftp:// 或类似的.

否 - DOM 不会公开对当前页面的 SSL 证书的访问权限,您可以访问的只是location.protocol它允许您检查您是否通过 HTTPS 交付

在 Web 浏览器上下文中,有两种 SSL 连接:一种由浏览器管理,另一种由您的代码(无论是 Java、Javascript...)自行管理。

对于第一种,您大多不走运,因为浏览器不会向您提供有关服务器证书链的详细信息。浏览器告诉您“这一切都是花花公子”,但无法让您检查浏览器是否被误入歧途。

对于第二种,这意味着您的代码将打开与服务器的连接并自行运行完整的 SSL 握手。当然,此时代码将看到来自服务器的证书链,并且能够以任意方式验证它,包括“直接信任”(客户端代码已经“知道”服务器公钥)或在至少使用特定的、预期的根 CA。这种方法有几个实际问题,需要付出代价才能解决:

  • 您必须嵌入完整的 SSL 实现。这不一定很大,但可能很棘手。由于您控制客户端和服务器代码,因此您可以将其缩小,因此您可以专注于您打算使用的确切协议版本和算法。
  • 如果使用没有JIT 编译器的解释器,性能可能会成为问题。
  • 只有当您可以确保客户端代码未被更改时,所有这些才有意义。使用 Javascript 检查有关下载 Javascript 代码本身的 SSL 连接的任何内容是没有用的:中间人可以更改 Javascript 代码以删除检查。
  • 在某些网络中,从客户端代码打开到服务器的原始连接是很棘手的,尤其是在代理方面。

为了提高性能,您将需要使用Java ME大多数 Java ME 实现都使用基本解释器,因此它不会比 Javascript 或 Flash 快,除了Java ME 标准库包括java.math.BigInteger一个任意大整数的算术实现,它通常作为本机代码实现,因此速度非常快。对于 SSL 握手所涉及的 RSA 或 DH 计算,您将需要它。

为了确保在客户端上运行正确的代码,Java ME 可以再次进行救援,因为 Java ME 小程序可以被签名这并不能真正解决您的问题,因为可以运行 Fiddler 的攻击者是可以在本地信任存储中插入自己的假 CA 的攻击者;同一个攻击者可以将他自己的假 CA 添加到另一个本地信任库,即用于验证 applet 签名证书的信任库。然而,这增加了一个很好的转折:如果客户端连接被拦截,事后取证检查可能会发现缓存的签名小程序,然后就会证明小程序是假的,而作为服务器维护者的你不是坏人。您无法获得这种免于身份验证的法律保护,但签名可以提供帮助。当然,这在很大程度上取决于上下文。

代理的问题很严重。很多本地网络,尤其是企业网络,不做NAT相反,所有外部流量都必须通过一些代理。用户的 Web 浏览器知道代理在哪里,但不知道您的 Javascript 或 Java 代码。此外,代理可能需要一些身份验证,这可能与本地会话凭据相关联;再次,浏览器透明地通过,而不是您的代码。为了解决这类问题,您可能会设想通过 HTTP 请求隧道传输 SSL 流量,这些请求将移交给框架提供的 HTTP 代码。这是可能的(大约十年前我已经做到了)但并不容易。


然而,这一切都闻起来很糟糕。您所说的这种中间人攻击只有在攻击者可以穿透 X.509 信任模型时才起作用,例如,通过在客户端系统中安装他自己的恶意 CA 作为受信任的 CA。由于操作系统软件更新使用这种信任模型,因此必须假设客户端系统在那时完全处于攻击者的控制之下,至少是潜在的。从某种意义上说,Fiddler 并不是邪恶的人使用的东西,因为 Fiddler 运作的条件也让上述邪恶的人能够实施更大更彻底的邪恶。

这可以概括为:从 Javascript 或 Java ME 客户端代码检查 SSL 连接的内容与客厅桌子上的漂亮便条一样无用,请潜在的窃贼自己打电话报警。

(不过可能在加拿大工作。)

鉴于您的威胁模型(检测代理 SSL 但不尝试篡改您的检查代码的代理),您可以在所有页面中嵌入 Javascript 代码,对内容进行校验和并将其与服务器计算的硬编码校验和进行比较,确定到达客户端的页面是否与服务器发送的页面相匹配。但是,我怀疑这里可能存在一些不重要的技术挑战,我不相信它会给你带来很多好处(请记住,恶意代理总是可以删除你的检查代码)。

您可能有兴趣了解瑞士并在华盛顿大学从事“网络绊线”工作。