A security vulnerability in all versions of the Transport Layer Security (TLS) protocol (including the older Secure Socket Layer (SSLv3)) can allow Man-In-The-Middle (MITM) type attacks where chosen plain text is injected as a prefix to a TLS connection. This vulnerability does not allow an attacker to decrypt or modify the intercepted network communication once the client and server have successfully negotiated a session between themselves. This vulnerability has been disclosed at:
and additional information is available at:
The fix for this issue was handled in two phases:
Phase 1: Until a protocol fix could be developed, an interim fix which 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. A fix which implements RFC 5746 and supports secure renegotiation is included in the following releases:
JDK Family | Vulnerable Releases | Phase 1 Fix (Disable Reneg.) | Phase 2 Fix (RFC 5746) |
---|---|---|---|
JDK and JRE 6 | Update 18 and earlier | Updates 19-21 | Update 22 |
JDK and JRE 5.0 | Update 23 and earlier | Updates 24-25 | Update 26 |
SDK and JRE 1.4.2 | Update 25 and earlier | Updates 26-27 | Update 28 |
NOTE: In the Phase 2 default configuration, there is no impact to applications that do not require renegotiation. Applications that require a renegotiation (e.g. web servers that initially allow for anonymous client browsing, but later require SSL/TLS authenticated clients):
The SunJSSE implementation re-enables renegotiation by default for connections to RFC 5746 compliant peers. 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 now has three "renegotiation interoperability modes." Each mode fully supports RFC 5746's secure renegotiation, but has these added semantics when communicating with an unupgraded peer:
Strict mode: Requires both client and server be upgraded to RFC 5746 and 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 mode distinctions above only affect a connection with an un-upgraded peer. Ideally, strict (full RFC 5746) mode should be used for all clients/servers, however it will take some time for all deployed SSL/TLS implementations to support RFC 5746, thus the interoperable mode will be the default for now.
Here is some additional interoperability information:
Client | Server | Mode |
---|---|---|
Updated | Updated | Secure Renegotiation in all modes. |
Legacy[1] | Updated | Strict: If clients do not send the proper RFC 5746 messages, initial connections will immediately be terminated by the server (SSLHandshakeException /handshake_failure). |
Interoperable: Initial connections from legacy clients allowed (missing RFC 5746 messages), but renegotiations will not be allowed by the server. [2][3] | ||
Insecure: Connections and renegotiations with legacy clients are allowed, but are vulnerable to the original MITM attack. | ||
Updated | Legacy[1] | Strict: If the server does not respond with the proper RFC 5746 messages, the client will immediately terminate the connection (SSLHandshakeException/handshake_failure ). |
Interoperable: The client will not require the proper initial RFC 5746 message from the server, but renegotiations will not be allowed by the client. [2][3] | ||
Insecure: Connections and renegotiations with legacy clients are allowed, but are vulnerable to the original MITM attack. | ||
Legacy[1] | Legacy[1] | Existing SSL/TLS behavior, vulnerable to the MITM attack. |
[1] Legacy means the original SSL/TLS specifications (i.e. non-RFC 5746).
[2] SunJSSE Phase 1 implementations (see above) reject renegotiations unless specifically re-enabled. If renegotiations are re-enabled, they will be treated as Legacy by the RFC 5746-compliant peer since they do not send the proper RFC 5746 messages.
[3] In SSL/TLS, renegotiations can be initiated by either side. Like the Phase 1 fix, applications communicating with an un-upgraded peer in Interoperable mode and that attempt to initiate renegotiation (via SSLSocket.startHandshake()
or SSLEngine.beginHandshake()
) will receive a SSLHandshakeException
(IOException
) and the connection will be shutdown (handshake_failure). Applications that receive a renegotiation request from a non-upgraded peer will respond according to the type of connection in place:
SSLHandshakeException
, and the connection will be closed (handshake_failure). ("no_renegotiation" is not defined in the SSLv3 spec.)To set these modes, two system properties are used:
sun.security.ssl.allowUnsafeRenegotiation
- Introduced in Phase 1, this controls whether legacy (unsafe) renegotiations are permitted.sun.security.ssl.allowLegacyHelloMessages
- Introduced in Phase 2, this allows the peer to handshake without requiring the proper RFC 5746 messages.mode | allowLegacyHelloMessages | allowUnsafeRenegotiation |
---|---|---|
Strict | false | false |
Interoperable (default) | true | false |
Insecure | true | true |
WARNING: It is not recommended to re-enable the insecure SSL/TLS renegotiation, as the vulnerability is once again present.
The various modes are set using the corresponding system properties, which must be set before the SunJSSE library is initialized. There are several ways to set these properties:
From the command line:
% java -Dsun.security.ssl.allowUnsafeRenegotiation=true Main
Within the application:
java.lang.System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", true);
In the Java Deployment environment (Plug-In/Web Start), there are several ways to set the system properties.
Use the Java Control Panel to set the Runtime Environment Property on a local/per-VM basis. This creates a local deployment.properties
file. Deployers can also distribute a enterprise-wide deployment.properties
file by using the deployment.config
mechanism. (See Deployment Configuration File and Properties.)
To set a property for a specific applet, use the HTML subtag <PARAM>
"java_arguments" within the <APPLET>
tag. (See Java Arguments.)
To set the property in a specific Java Web Start application or applet using the new Plugin2 (6u10+), use the JNLP "property" sub-element of the "resources" element. (See Resources Element.)
All peers should be updated to RFC 5746-compliant implementation as soon as possible. Even with this RFC 5746 fix, communications with unupgraded peers will be impacted 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 which may initially allow weak ciphersuites but later need stronger ones. The alternative is to require client authentication/strong ciphersuites 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, one can restructure the server to eliminate the "browse mode" and require all initial connections be strong.
Another alternative is to break the server into two entities, with the "browse mode" occuring on server, and a second for the more secure mode. When the point is reached, transfer any relevent information between the servers.
Both of these options couple require a fair amount of work, but will not reopen the original hole.
Set renegotiation interoperability mode to "insecure" using the system properties (see above 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. Please see the IETF email discussion from November 2009 to February 2010 for the relevant technical discussions.
RFC 5746 allows for clients to send either a SCSV or RI in the first ClientHello. For maximum interoperability, SunJSSE will use the SCSV by default, as a few TLS and SSL servers do not handle unknown extensions correctly. The presence of the SCSV in the enabled Cipher Suites (i.e. SSLSocket.setEnabledCipherSuites()/SSLEngine.setEnabledCipherSuites()
will determine 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, SCSV will be sent in the initial ClientHello.
As mentioned above, the Phase 1 Fix was to disable renegotiations by default until a RFC 5746-compliant fix could be developed. Renegotiations could be reenabled by setting the sun.security.ssl.allowUnsafeRenegotiation
system property. The Phase 2 fix uses the same system property, with the addition of the sun.security.ssl.allowUnsafeRenegotiation
system property to require the use of RFC 5746 messages.
All applications should upgrade to the Phase 2 RFC 5746 fix as soon as possible.