Java http clients and POODLE
Asked Answered
S

4

16

Regarding the POODLE vulnerability, if I understand it correctly, it requires a client that automatically downgrades TLS protocol to SSLv3 when failing to establish a secure channel with a server using higher version protocol advertised by the server.

Do the common java HTTP client libraries, specifically javax.net.ssl.HttpsURLConnection and Apache HttpClient, automatically downgrade the TLS protocol when failing to establish TLS session with a server? If not, am I correct that they are immune from he POODLE attack unless either (a) the server only supports SSLv3, or (b) a logic at a higher level performs the downgrade?

I'm looking for something like http://blog.hagander.net/archives/222-A-few-short-notes-about-PostgreSQL-and-POODLE.html but for Java clients.

Swaim answered 17/10, 2014 at 16:46 Comment(1)
Refer to my answer at [Disable SSLv3 in HttpsUrlConnection in Android][1] [1]: https://mcmap.net/q/35819/-how-to-disable-sslv3-in-android-for-httpsurlconnectionZins
P
23

Apache HttpClient does not implement any of the TLS protocol aspects. It relies on JSSE APIs to do TLS/SSL handshaking and to establish secure SSL sessions. With the exception of SSL hostname verification logic, as far as TLS/SSL is concerned Apache HttpClient is as secure (or as vulnerable) as the JRE it is running in.


Update: HttpClient 4.3 by default always uses TLS, so, unless one explicitly configures it to use SSLv3 HttpClient should not be vulnerable to exploits based on POODLE.

This turned out to be wrong. One MUST explicitly remove SSLv3 from the list of supported protocols!

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();

Update 2: As of version 4.3.6 HttpClient disables all versions of SSL (including SSLv3) by default.

Panayiotis answered 18/10, 2014 at 11:58 Comment(6)
thx - do you care to enlight us about how the JRE is doing concerning the POODLE attack, if you know?Hamachi
@Hamachi Oracle is likely to remove support for SSLv3 at some point but for now one needs to make sure that SSL protocol is disabled or, to be exact, TLS is the only protocol enabledPanayiotis
If SSLv3 is a supported protocol, but the server supports higher version (e.g. TLSv1) with available cipher suites, the client will try to use the the higher version. POODLE relies on sabotaging the handshake and having the client drop down to SSLv3 to handle the error. Per my understanding, that's not specified by the protocol itself, but rather something that browsers do. Will HttpClient drop to SSLv3?Swaim
@Swaim As I said the details of TLS handshake are completely out of HttpClient control. However if the client has been configured to allow TLS protocols only downgrade to SSLv3 should failPanayiotis
@oleg I understand your explanation for disabling SSLv3 and I agree that it's the best thing to do. However, we are pulling in many thirdparty dependencies, and it's very hard to trace through all the places in their code where to see how they might be using HttpClient. I want to understand the risk with these out of the box. Protocol downgrade is not part of the TLS handshake; it's something that's done at a higher level. So if Java doesn't do it, and HttpClient doesn't do it, then I have less to worry about.Swaim
@Swaim HttpClient makes no attempts to apply a different SSL configuration if the one provided at construction time fails. I can guarantee that. If SSL session cannot be established with the given SSLContext no attempts will be made to circumvent thatPanayiotis
L
12

You MUST disable SSL v3.0 on java clients if you use https.

This can be done by adding this property on java 6/7:

-Dhttps.protocols="TLSv1"

And for Java 8 :

-Dhttps.protocols="TLSv1,TLSv1.1,TLSv1.2"

-Djdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2"

Source : http://www.oracle.com/technetwork/java/javase/documentation/cve-2014-3566-2342133.html

Longoria answered 26/10, 2014 at 21:41 Comment(2)
Thank you for the link to the official guidance from Oracle. The https.protocols setting only works with HttpsURLConnection. It doesn't prevent Apache HttpClient and other implementations from configuring a JSSE context that supports SSLv3.Swaim
For completeness to @ykaganovich's comment, setting https.protocols also does not affect any server sockets that may be created unless they have been explicitly programmed to consult https.protocols. For example, Apache Tomcat ignores https.protocols, but you can configure Tomcat in complex ways including cherry-picking protocols.Cocytus
C
3

Apache HttpClient 4.3.6 disables SSLv3 by default.

Here's an excerpt from Apache HC 4.3.6 release notes

Release 4.3.6

HttpClient 4.3.6 (GA) is a maintenance release that fixes several problems with HttpClient OSGi bundle as well as some other issues reported since release 4.3.5.

Please note that as of this release HttpClient disables all versions of SSL (including SSLv3) in favor of the TLS protocol by default. Those users who wish to continue using SSLv3 need to explicitly enable support for it.

Users of all HttpClient versions are advised to upgrade.

Changelog:

  • SSLv3 protocol is disabled by default Contributed by Oleg Kalnichevski

Update: If you are running on JVM having version >= Java 1.8 Update 31 SSLv3 is disabled by default.Check out the release notes

Coterie answered 7/11, 2014 at 3:43 Comment(1)
Include the full link to the release notes? apache.org/dist/httpcomponents/httpclient/…Miru
E
0

After spending considerable time trying to figure out why TLSv1.2 was being used despite setting -Dhttps.protocols="TLSv1" we finally found this post. The magic flag is indeed -Djdk.tls.client.protocols="TLSv1" and our Apache Axis 1.4 client works again. So in case you move from Java 7 to Java 8 you may need to add this flag as pre JAVA 8 used TLSv1 as default whereas JAVA 8 uses TLSv1.2

Thanks!

Elysia answered 9/2, 2015 at 15:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.