In the fall of 2009, a flaw was discovered in the SSL/TLS protocols. A fix to the protocol was developed by the IETF TLS Working Group, and current versions of the JDK contain this fix. This section describes the situation in much more detail, along with interoperability issues when communicating with older implementations that do not contain this protocol fix.
The vulnerability allowed for man-in-the-middle (MITM) attacks where chosen plain text could be injected as a prefix to a TLS connection. This vulnerability did not allow an attacker to decrypt or modify the intercepted network communication once the client and server have successfully negotiated a session between themselves.
Additional information is available at CVE-2009-3555 (posted on Mitre's Common Vulnerabilities and Exposures List, 2009).
The fix for this issue was handled in two phases:
Phase 1: Until a protocol fix could be developed, an interim fix that disabled SSL/TLS renegotiations by default was made available in the March 30, 2010 Java SE and Java for Business Critical Patch Update.
Phase 2: The IETF issued RFC 5746, which addresses the renegotiation protocol flaw. The following table lists the JDK and JRE releases that include the fix which implements RFC 5746 and supports secure renegotiation.
JDK Family | Vulnerable Releases | Phase 1 Fix (Disable Renegotiations) | Phase 2 Fix (RFC 5746) |
---|---|---|---|
JDK and JRE 6 | Update 18 and earlier | Updates 19 through 21 | Update 22 |
JDK and JRE 5.0 | Update 23 and earlier | Updates 24 through 25 | Update 26 |
JDK and JRE 1.4.2 | Update 25 and earlier | Updates 26 through 27 | Update 28 |
Note: Applications that do not require renegotiations are not affected by the Phase 2 default configuration. However applications that require renegotiations (for example, web servers that initially allow for anonymous client browsing, but later require SSL/TLS authenticated clients):
The SunJSSE implementation reenables renegotiations by default for connections to peers compliant with RFC 5746. That is, both the client and server must support RFC 5746 in order to securely renegotiate. SunJSSE provides some interoperability modes for connections with peers that have not been upgraded, but users are strongly encouraged to update both their client and server implementations as soon as possible.
With the Phase 2 fix, SunJSSE has three renegotiation interoperability modes. Each mode fully supports the RFC 5746 secure renegotiation, but has these added semantics when communicating with a peer that has not been upgraded:
Strict mode: Requires both client and server be upgraded to RFC 5746 and to send the proper RFC 5746 messages. If not, the initial (or subsequent) handshaking will fail and the connection will be terminated.
Interoperable mode (default): Use of the proper RFC 5746 messages is optional; however, legacy (original SSL/TLS specifications) renegotiations are disabled if the proper messages are not used. Initial legacy connections are still allowed, but legacy renegotiations are disabled. This is the best mix of security and interoperability, and is the default setting.
Insecure mode: Permits full legacy renegotiation. Most interoperable with legacy peers but vulnerable to the original MITM attack.
The three mode distinctions only affect a connection with a peer that has not been upgraded. Ideally, strict (full RFC 5746) mode should be used for all clients and servers; however, it will take some time for all deployed SSL/TLS implementations to support RFC 5746, because the interoperable mode is the current default.
The following table contains interoperability information about the modes for various cases in which the client and/or server are either updated to support RFC 5746 or not.
Client | Server | Mode |
---|---|---|
Updated | Updated |
Secure renegotiation in all modes. |
Legacy Footnote 1 | Updated |
|
Updated | Legacy Footnote 1 |
|
Legacy Footnote 1 | Legacy Footnote 1 | Existing SSL/TLS behavior, vulnerable to the MITM attack. |
Footnote 1 "Legacy" means the original SSL/TLS specifications (that is, not RFC 5746).
Footnote 2 SunJSSE Phase 1 implementations reject renegotiations unless specifically reenabled. If renegotiations are reenabled, then they will be treated as "Legacy" by the peer that is compliant with RFC 5746, because they do not send the proper RFC 5746 messages.
Footnote 3 In SSL/TLS, renegotiations can
be initiated by either side. Like the Phase 1 fix, applications
communicating with a peer that has not been upgraded in
Interoperable mode and that attempt to initiate renegotiation (via
SSLSocket.startHandshake()
or
SSLEngine.beginHandshake()
) will receive an
SSLHandshakeException
(IOException
) and
the connection will be shut down (handshake_failure
).
Applications that receive a renegotiation request from a peer that
has not been upgraded will respond according to the type of
connection in place:
no_renegotiation(100)
will be sent to the peer and the connection will remain open. Older
versions of SunJSSE will shut down the connection when a
no_renegotiation
alert is received.SSLHandshakeException
,
and the connection will be closed (handshake_failure
).
The no_renegotiation
alert is not defined in the SSLv3
specification.The following system properties are used to set the mode:
sun.security.ssl.allowUnsafeRenegotiation
(introduced in Phase 1) controls whether legacy (unsafe)
renegotiations are permitted.sun.security.ssl.allowLegacyHelloMessages
(introduced in Phase 2) allows the peer to perform the handshake
process without requiring the proper RFC 5746 messages.Mode | allowLegacyHelloMessages |
allowUnsafeRenegotiation |
---|---|---|
Strict | false | false |
Interoperable (default) | true | false |
Insecure | true | true |
Caution: Do not reenable the insecure SSL/TLS renegotiation, as this would reestablish the vulnerability.
For information about how to configure a specific mode by setting a system property, see How to Specify a java.lang.System Property.
All peers should be updated to RFC 5746-compliant implementation as soon as possible. Even with this RFC 5746 fix, communications with peers that have not been upgraded will be affected if a renegotiation is necessary. Here are a few suggested options:
Restructure the peer to not require renegotiation.
Renegotiations are typically used by web servers that initially allow for anonymous client browsing but later require SSL/TLS authenticated clients, or that may initially allow weak cipher suites but later need stronger ones. The alternative is to require client authentication or strong cipher suites during the initial negotiation. There are a couple of options for doing so:
If an application has a browse mode until a certain point is reached and a renegotiation is required, then you can restructure the server to eliminate the browse mode and require all initial connections be strong.
Break the server into two entities, with the browse mode occurring on one entity, and using a second entity for the more secure mode. When the renegotiation point is reached, transfer any relevant information between the servers.
Both of these options require a fair amount of work, but will not reopen the original security flaw.
Set renegotiation interoperability mode to "insecure" using the system properties.
See the Description of the Phase 2 Fix for information and warnings.
RFC 5746 defines two new data structures, which are mentioned here for advanced users:
Either of these can be used to signal that an implementation is RFC 5746-compliant and can perform secure renegotiations. For more relevant technical discussions, see the IETF email discussion from November 2009 to February 2010.
RFC 5746 enables clients to send either an SCSV or RI in the
first ClientHello
. For maximum interoperability,
SunJSSE uses the SCSV by default, as a few TLS/SSL servers do not
handle unknown extensions correctly. The presence of the SCSV in
the enabled cipher suites
(SSLSocket.setEnabledCipherSuites()
or
SSLEngine.setEnabledCipherSuites()
) determines whether
the SCSV is sent in the initial ClientHello
, or if an
RI should be sent instead.
SSLv2 does not support SSL/TLS extensions. If the
SSLv2Hello
protocol is enabled, then the SCSV is sent
in the initial ClientHello
.
As previously mentioned, the Phase 1 Fix was to disable
renegotiations by default until a fix compliant with RFC 5746 could
be developed. Renegotiations could be reenabled by setting the
sun.security.ssl.allowUnsafeRenegotiation
system
property. The Phase 2 fix uses the same
sun.security.ssl.allowUnsafeRenegotiation
system
property, but also requires it to use RFC 5746 messages.
All applications should upgrade to the Phase 2 RFC 5746 fix as soon as possible.
Server certificate change in an SSL/TLS renegotiation may be unsafe:
Two certificates can be considered to represent the same identity:
Starting with JDK 8u25, unsafe server certificate change in
SSL/TLS renegotiations is not allowed by default. The new system
property jdk.tls.allowUnsafeServerCertChange
, can be
used to define whether unsafe server certificate change in an
SSL/TLS renegotiation should be restricted or not.
The default value of this system property is
"false"
.
Caution: DO NOT set the system property to
"true"
unless it is really necessary, as this would
re-establish the unsafe server certificate change
vulnerability.