[JAVA-4522] Connection string parameter tlsInsecure is not supported Created: 08/Mar/22  Updated: 04/May/22

Status: Backlog
Project: Java Driver
Component/s: Configuration
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major - P3
Reporter: Fabian Kreis Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: external-user
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Version: 
mongodb-driver-core-4.4.2

 

Context:

Everything works fine when we import the appropriate mongoDB certs into the truststore.

However, we want to use tlsInsecure=true for local development only to make setups easier for the developers.

Hence, I am defining a mongodb uri like

 

mongodb://[...]&tlsInsecure=true

 

 

Actual behvior:

The connection string query parameter 'tlsInsecure' is being ignored

 

com.mongodb.MongoSocketWriteException: Exception sending messagecom.mongodb.MongoSocketWriteException: Exception sending message 
at com.mongodb.internal.connection.InternalStreamConnection.translateWriteException(InternalStreamConnection.java:689)
at com.mongodb.internal.connection.InternalStreamConnection.sendMessage(InternalStreamConnection.java:560) 
at com.mongodb.internal.connection.InternalStreamConnection.sendCommandMessage(InternalStreamConnection.java:386)
at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:335) 
at com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:96)
at com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:44) 
at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:131)
at com.mongodb.internal.connection.InternalStreamConnectionInitializer.startHandshake(InternalStreamConnectionInitializer.java:73)
at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:182) 
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.lookupServerDescription(DefaultServerMonitor.java:188)
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:152) 
at java.base/java.lang.Thread.run(Thread.java:833)Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131) 
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:370) 
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:313) 
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308) 
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1357)
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1232) 
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1175) 
at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:480) 
at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:458) 
at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:200) 
at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172) 
at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1500) 
at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1415) 
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:450) 
at java.base/sun.security.ssl.SSLSocketImpl.ensureNegotiated(SSLSocketImpl.java:915) 
at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1285) 
at com.mongodb.internal.connection.SocketStream.write(SocketStream.java:99) 
at com.mongodb.internal.connection.InternalStreamConnection.sendMessage(InternalStreamConnection.java:557) .
.. 10 common frames omitted
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439) 
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306) 
at java.base/sun.security.validator.Validator.validate(Validator.java:264) 
at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231) 
at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132) 
at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1341) 
... 24 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) 
at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) 
at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297) 
at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434) 
... 29 common frames omitted

 

 

Expected Behavior:*+
+*The urioption 'tlsInsecure' should not be ignored. Instead, any mongoDB cert should be accepted.

 

Solution hints:

I believe there is two places to change:

1) The class com.mongodb.ConnectionString does not have a field "tlsInsecure". Such a field (along with accessors) should be added. In line 576 this new field should be asigned instead of sslInvalidHostnameAllowed.
I guess this is a copy/paste error from the case above.

2) The new introduced tlsInsecure information from 1) has to be evaluated in com.mongodb.connection.SslSettings.Builder#applyConnectionString()



 Comments   
Comment by Jeffrey Yemin [ 14/Mar/22 ]

f.kreis@enbw.com thanks for providing this context. Local development is certainly a common use case, but I think most users choose different workarounds. The ones that I'm aware of are:

  1. Don't enable TLS (probably by far the most common)
  2. Create a new trust store containing the signing certificate and use javax.net.ssl.trustStore to refer to it
  3. Add the signing certificate to the system trust store

Meanwhile, we will consider whether and how the driver can safely support the tlsInsecure configuration parameter.

Comment by Fabian Kreis [ 14/Mar/22 ]

Jeffrey, thank you for your response!

I am aware of the option to provide my own SSLContext. It is good to have that option, we are using it as a "workaround" for local development while the tlsInsecure option is not supported by the mongoDB driver.

However, this requires additional code which also will be part of the production code. The same code would have to be written, tested, and maintained by all users of the mongoDB driver which want to achieve the same thing. If on the other hand this would be implemented within the mongoDB driver all users would benefit from that single, well-maintained implementation.

Also, I as a mongoDB user would expect that all featues which are documented in https://docs.mongodb.com/manual/reference/connection-string/#connection-string-options are supported by all drivers. It is very unexpected for me that some of options are supported, and others are not. It took me some time to figure out that the reason for my dysfunctional setup was not caused by me. Especially, as there is a hint about mongo shell (“This connection string option is not available for the mongo shell. Use the command-line option instead.”) but not for the Java driver.

In summary, I still believe that this option should be supported by the Java driver as it is documented in https://docs.mongodb.com/manual/reference/connection-string/#connection-string-options .

Comment by Jeffrey Yemin [ 11/Mar/22 ]

f.kreis@enbw.com it's intentional that the driver does not support this option via URI. It's not the same as tls/sslInvalidHostnameAllowed, which is supported.

The reason it's not supported is due to the abstractions provided by the JDK for TLS configuration. By default, the driver creates TLS-enabled sockets via the socket factory from javax.net.ssl.SSLContext.getDefault().getSocketFactory(). The default behavior of this socket factory is to enforce TLS certificate validation using the root certificates that are included with the JDK. These certificates can be altered via the system property javax.net.ssl.trustStore. But certificate validation can not just be turned off. In order to do it, you have to create a new SSLContext with a TrustManager that trusts all certificates. This is not something that we believe that the driver should do directly, via a simple connection string parameter. Instead, what the driver lets you do is configure your own SSLContext for the driver to use to create sockets. So you can disable certificate validation, but you have to do it in code, by creating an SSLContext that disables the validation.

Hope this helps.

Comment by Esha Bhargava [ 11/Mar/22 ]

f.kreis@enbw.com Thank you for reporting this issue! We'll look into it and get back to you soon.

Generated at Thu Feb 08 09:02:18 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.