VYPR
Medium severity5.9NVD Advisory· Published Jan 12, 2017· Updated May 6, 2026

CVE-2016-10027

CVE-2016-10027

Description

Race condition in the XMPP library in Smack before 4.1.9, when the SecurityMode.required TLS setting has been set, allows man-in-the-middle attackers to bypass TLS protections and trigger use of cleartext for client authentication by stripping the "starttls" feature from a server response.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.igniterealtime.smack:smack-coreMaven
< 4.1.94.1.9

Affected products

2

Patches

2
a9d5cd4a611f

Move TLS Required check at the end of connect()

https://github.com/igniterealtime/SmackFlorian SchmausNov 12, 2016via ghsa
2 files changed · +9 10
  • smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java+8 0 modified
    @@ -46,6 +46,7 @@
     import org.jivesoftware.smack.SmackException.NoResponseException;
     import org.jivesoftware.smack.SmackException.NotConnectedException;
     import org.jivesoftware.smack.SmackException.ResourceBindingNotOfferedException;
    +import org.jivesoftware.smack.SmackException.SecurityRequiredByClientException;
     import org.jivesoftware.smack.SmackException.SecurityRequiredException;
     import org.jivesoftware.smack.XMPPException.StreamErrorException;
     import org.jivesoftware.smack.XMPPException.XMPPErrorException;
    @@ -373,6 +374,13 @@ public synchronized AbstractXMPPConnection connect() throws SmackException, IOEx
             // Wait with SASL auth until the SASL mechanisms have been received
             saslFeatureReceived.checkIfSuccessOrWaitOrThrow();
     
    +        // If TLS is required but the server doesn't offer it, disconnect
    +        // from the server and throw an error. First check if we've already negotiated TLS
    +        // and are secure, however (features get parsed a second time after TLS is established).
    +        if (!isSecureConnection() && getConfiguration().getSecurityMode() == SecurityMode.required) {
    +            throw new SecurityRequiredByClientException();
    +        }
    +
             // Make note of the fact that we're now connected.
             connected = true;
             callConnectionConnectedListener();
    
  • smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java+1 10 modified
    @@ -29,9 +29,7 @@
     import org.jivesoftware.smack.SmackException.NoResponseException;
     import org.jivesoftware.smack.SmackException.NotConnectedException;
     import org.jivesoftware.smack.SmackException.ConnectionException;
    -import org.jivesoftware.smack.SmackException.SecurityRequiredByClientException;
     import org.jivesoftware.smack.SmackException.SecurityRequiredByServerException;
    -import org.jivesoftware.smack.SmackException.SecurityRequiredException;
     import org.jivesoftware.smack.SynchronizationPoint;
     import org.jivesoftware.smack.XMPPException.StreamErrorException;
     import org.jivesoftware.smack.XMPPConnection;
    @@ -917,7 +915,7 @@ protected void setWriter(Writer writer) {
         }
     
         @Override
    -    protected void afterFeaturesReceived() throws SecurityRequiredException, NotConnectedException, InterruptedException {
    +    protected void afterFeaturesReceived() throws NotConnectedException, InterruptedException {
             StartTls startTlsFeature = getFeature(StartTls.ELEMENT, StartTls.NAMESPACE);
             if (startTlsFeature != null) {
                 if (startTlsFeature.required() && config.getSecurityMode() == SecurityMode.disabled) {
    @@ -929,13 +927,6 @@ protected void afterFeaturesReceived() throws SecurityRequiredException, NotConn
                     sendNonza(new StartTls());
                 }
             }
    -        // If TLS is required but the server doesn't offer it, disconnect
    -        // from the server and throw an error. First check if we've already negotiated TLS
    -        // and are secure, however (features get parsed a second time after TLS is established).
    -        if (!isSecureConnection() && startTlsFeature == null
    -                        && getConfiguration().getSecurityMode() == SecurityMode.required) {
    -            throw new SecurityRequiredByClientException();
    -        }
     
             if (getSASLAuthentication().authenticationSuccessful()) {
                 // If we have received features after the SASL has been successfully completed, then we
    
059ee99ba0d5

Move TLS Required check at the end of connect()

https://github.com/igniterealtime/SmackFlorian SchmausNov 12, 2016via ghsa
2 files changed · +11 10
  • smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java+1 0 modified
    @@ -362,6 +362,7 @@ public synchronized AbstractXMPPConnection connect() throws SmackException, IOEx
     
             // Perform the actual connection to the XMPP service
             connectInternal();
    +
             return this;
         }
     
    
  • smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java+10 10 modified
    @@ -28,10 +28,9 @@
     import org.jivesoftware.smack.SmackException.AlreadyLoggedInException;
     import org.jivesoftware.smack.SmackException.NoResponseException;
     import org.jivesoftware.smack.SmackException.NotConnectedException;
    -import org.jivesoftware.smack.SmackException.ConnectionException;
     import org.jivesoftware.smack.SmackException.SecurityRequiredByClientException;
    +import org.jivesoftware.smack.SmackException.ConnectionException;
     import org.jivesoftware.smack.SmackException.SecurityRequiredByServerException;
    -import org.jivesoftware.smack.SmackException.SecurityRequiredException;
     import org.jivesoftware.smack.SynchronizationPoint;
     import org.jivesoftware.smack.XMPPException.StreamErrorException;
     import org.jivesoftware.smack.XMPPConnection;
    @@ -857,6 +856,14 @@ protected void connectInternal() throws SmackException, IOException, XMPPExcepti
             // Wait with SASL auth until the SASL mechanisms have been received
             saslFeatureReceived.checkIfSuccessOrWaitOrThrow();
     
    +        // If TLS is required but the server doesn't offer it, disconnect
    +        // from the server and throw an error. First check if we've already negotiated TLS
    +        // and are secure, however (features get parsed a second time after TLS is established).
    +        if (!isSecureConnection() && getConfiguration().getSecurityMode() == SecurityMode.required) {
    +            shutdown();
    +            throw new SecurityRequiredByClientException();
    +        }
    +
             // Make note of the fact that we're now connected.
             connected = true;
             callConnectionConnectedListener();
    @@ -897,7 +904,7 @@ protected void setWriter(Writer writer) {
         }
     
         @Override
    -    protected void afterFeaturesReceived() throws SecurityRequiredException, NotConnectedException {
    +    protected void afterFeaturesReceived() throws NotConnectedException {
             StartTls startTlsFeature = getFeature(StartTls.ELEMENT, StartTls.NAMESPACE);
             if (startTlsFeature != null) {
                 if (startTlsFeature.required() && config.getSecurityMode() == SecurityMode.disabled) {
    @@ -909,13 +916,6 @@ protected void afterFeaturesReceived() throws SecurityRequiredException, NotConn
                     send(new StartTls());
                 }
             }
    -        // If TLS is required but the server doesn't offer it, disconnect
    -        // from the server and throw an error. First check if we've already negotiated TLS
    -        // and are secure, however (features get parsed a second time after TLS is established).
    -        if (!isSecureConnection() && startTlsFeature == null
    -                        && getConfiguration().getSecurityMode() == SecurityMode.required) {
    -            throw new SecurityRequiredByClientException();
    -        }
     
             if (getSASLAuthentication().authenticationSuccessful()) {
                 // If we have received features after the SASL has been successfully completed, then we
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

11

News mentions

0

No linked articles in our index yet.