Unsafe certificate trust¶
ID: java/unsafe-cert-trustKind: problemSecurity severity: 9.8Severity: warningPrecision: mediumTags: - security - external/cwe/cwe-273Query suites: - java-security-extended.qls - java-security-and-quality.qls
Click to see the query in the CodeQL repository
Java offers two mechanisms for SSL authentication - trust manager and hostname verifier (the later is checked by thejava/insecure-hostname-verifier query). The trust manager validates the peer’s certificate chain while hostname verification establishes that the hostname in the URL matches the hostname in the server’s identification.
WhenSSLSocket orSSLEngine are created without a securesetEndpointIdentificationAlgorithm, hostname verification is disabled by default.
This query checks whethersetEndpointIdentificationAlgorithm is missing, thereby making the application vulnerable to man-in-the-middle attacks. The query also covers insecure configurations ofcom.rabbitmq.client.ConnectionFactory.
Recommendation¶
Validate SSL certificates in SSL authentication.
Example¶
The following two examples show two ways of configuring SSLSocket/SSLEngine. In the ‘BAD’ case,setEndpointIdentificationAlgorithm is not called, thus no hostname verification takes place. In the ‘GOOD’ case,setEndpointIdentificationAlgorithm is called.
publicstaticvoidmain(String[]args){{SSLContextsslContext=SSLContext.getInstance("TLS");SSLEnginesslEngine=sslContext.createSSLEngine();SSLParameterssslParameters=sslEngine.getSSLParameters();sslParameters.setEndpointIdentificationAlgorithm("HTTPS");//GOOD: Set a valid endpointIdentificationAlgorithm for SSL engine to trigger hostname verificationsslEngine.setSSLParameters(sslParameters);}{SSLContextsslContext=SSLContext.getInstance("TLS");SSLEnginesslEngine=sslContext.createSSLEngine();//BAD: No endpointIdentificationAlgorithm set}{SSLContextsslContext=SSLContext.getInstance("TLS");finalSSLSocketFactorysocketFactory=sslContext.getSocketFactory();SSLSocketsocket=(SSLSocket)socketFactory.createSocket("www.example.com",443);SSLParameterssslParameters=sslEngine.getSSLParameters();sslParameters.setEndpointIdentificationAlgorithm("HTTPS");//GOOD: Set a valid endpointIdentificationAlgorithm for SSL socket to trigger hostname verificationsocket.setSSLParameters(sslParameters);}{com.rabbitmq.client.ConnectionFactoryconnectionFactory=newcom.rabbitmq.client.ConnectionFactory();connectionFactory.useSslProtocol();connectionFactory.enableHostnameVerification();//GOOD: Enable hostname verification for rabbitmq ConnectionFactory}{com.rabbitmq.client.ConnectionFactoryconnectionFactory=newcom.rabbitmq.client.ConnectionFactory();connectionFactory.useSslProtocol();//BAD: Hostname verification for rabbitmq ConnectionFactory is not enabled}}
References¶
SSLParameters.setEndpointIdentificationAlgorithm documentation.
RabbitMQ:ConnectionFactory.enableHostnameVerification documentation.
RabbitMQ:Using TLS in the Java Client.
CVE-2018-17187: Apache Qpid Proton-J transport issue with hostname verification.
CVE-2018-8034: Apache Tomcat - host name verification when using TLS with the WebSocket client.
CVE-2018-11087: Pivotal Spring AMQP vulnerability due to lack of hostname validation.
CVE-2018-11775: TLS hostname verification issue when using the Apache ActiveMQ Client.
Common Weakness Enumeration:CWE-273.