Java HTTP客户端和POODLE问题

16

关于POODLE漏洞,如果我理解正确,它要求客户端在与服务器使用高版本协议建立安全通道失败时,自动降级TLS协议至SSLv3。

常见的Java HTTP客户端库,特别是javax.net.ssl.HttpsURLConnection和Apache HttpClient,在无法建立TLS会话时是否会自动降级TLS协议?如果不会,那么我的理解是它们免疫POODLE攻击,除非(a)服务器仅支持SSLv3,或者(b)较高级别的逻辑执行降级操作。

我正在寻找类似http://blog.hagander.net/archives/222-A-few-short-notes-about-PostgreSQL-and-POODLE.html的Java客户端解释。


1
请参考我在Android中禁用HttpsUrlConnection中的SSLv3的回答。 - Bhavit S. Sengar
4个回答

23

Apache HttpClient没有实现任何TLS协议方面的内容。它依赖于JSSE API进行TLS/SSL握手和建立安全的SSL会话。除了SSL主机名验证逻辑之外,就TLS/SSL而言,Apache HttpClient与其运行的JRE一样安全(或易受攻击)。


更新:HttpClient 4.3默认始终使用TLS,因此,除非明确配置为使用SSLv3,否则HttpClient应该不会容易受到基于POODLE的攻击威胁

结果证明这是错误的。一个必须明确地将SSLv3从支持的协议列表中删除!

SSLContext sslContext = SSLContexts.custom()
        .useTLS() // Only this turned out to be not enough
        .build();
SSLConnectionSocketFactory sf = new SSLConnectionSocketFactory(
        sslContext,
        new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"},
        null,
        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient client = HttpClients.custom()
        .setSSLSocketFactory(sf)
        .build();

更新2:从版本4.3.6开始,HttpClient默认禁用所有版本的SSL(包括SSLv3)。


谢谢 - 如果您知道的话,您是否愿意告诉我们JRE在POODLE攻击方面的情况? - luksch
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - ok2c
如果SSLv3是受支持的协议,但服务器支持更高版本(例如TLSv1)并具有可用的密码套件,则客户端将尝试使用更高版本。 POODLE依赖于破坏握手并使客户端降级到SSLv3以处理错误。据我理解,这不是协议本身指定的,而是浏览器执行的操作。HttpClient会降级到SSLv3吗? - ykaganovich
1
正如我所说,TLS握手的细节完全不受HttpClient控制。但是,如果客户端已配置为仅允许TLS协议,则降级到SSLv3应该失败。 - ok2c
@oleg 我理解你关于禁用SSLv3的解释,并且我同意这是最好的做法。然而,我们引入了许多第三方依赖项,很难跟踪它们代码中的所有位置,以查看它们可能如何使用HttpClient。我想了解这些默认设置的风险。协议降级不是TLS握手的一部分;它是在更高层次上完成的。因此,如果Java不执行它,HttpClient也不执行它,那么我就不用太担心了。 - ykaganovich
3
HttpClient在构造时提供的SSL配置失败时,不会尝试应用不同的SSL配置。 我可以保证这一点。 如果无法使用给定的SSLContext建立SSL会话,则不会尝试规避此问题。 - ok2c

12

5
感谢提供来自Oracle的官方指南链接。 https.protocols 设置仅适用于 HttpsURLConnection,不能阻止 Apache HttpClient 和其他实现配置支持 SSLv3 的 JSSE 上下文。 - ykaganovich
为了完整性,根据@ykaganovich的评论,设置https.protocols也不会影响任何可能创建的服务器套接字,除非它们已经被明确地编程为查询https.protocols。例如,Apache Tomcat忽略https.protocols,但您可以以复杂的方式配置Tomcat,包括挑选协议。 - Christopher Schultz

3

Apache HttpClient 4.3.6默认禁用SSLv3。

以下是Apache HC 4.3.6发布说明的摘录:

发布4.3.6

HttpClient 4.3.6 (GA)是一个维护版本,修复了HttpClient OSGi捆绑包以及自发布4.3.5以来报告的一些其他问题。

请注意,自此版本起HttpClient默认禁用所有版本的SSL(包括SSLv3),而使用TLS协议。希望继续使用SSLv3的用户需要显式启用其支持。

建议所有HttpClient版本的用户进行升级。

更新日志:

  • 默认禁用SSLv3协议 贡献者Oleg Kalnichevski

更新:如果您在运行版本>= Java 1.8 Update 31的JVM上,则默认禁用SSLv3。查看发行说明


2
是否包含完整的发布说明链接?https://www.apache.org/dist/httpcomponents/httpclient/RELEASE_NOTES-4.3.x.txt - rbellamy

0
花费了相当长的时间来尝试弄清楚为什么会使用TLSv1.2,尽管设置了-Dhttps.protocols="TLSv1",我们最终找到了这篇文章。神奇的标志确实是-Djdk.tls.client.protocols="TLSv1",我们的Apache Axis 1.4客户端再次正常工作了。
所以,如果你从Java 7转移到Java 8,你可能需要添加这个标志,因为在JAVA 8之前默认使用TLSv1,而JAVA 8使用TLSv1.2。
谢谢!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接