CodeQL documentation

Unsafe certificate trust

ID: java/unsafe-cert-trust
Kind: problem
Security severity: 9.8
Severity: warning
Precision: medium
Tags:
   - security
   - external/cwe/cwe-273
Query 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 the java/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.

When SSLSocket or SSLEngine are created without a secure setEndpointIdentificationAlgorithm, hostname verification is disabled by default.

This query checks whether setEndpointIdentificationAlgorithm is missing, thereby making the application vulnerable to man-in-the-middle attacks. The query also covers insecure configurations of com.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.

public static void main(String[] args) {

	{
		SSLContext sslContext = SSLContext.getInstance("TLS");
		SSLEngine sslEngine = sslContext.createSSLEngine();
		SSLParameters sslParameters = sslEngine.getSSLParameters();
		sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //GOOD: Set a valid endpointIdentificationAlgorithm for SSL engine to trigger hostname verification
		sslEngine.setSSLParameters(sslParameters);
	}

	{
		SSLContext sslContext = SSLContext.getInstance("TLS");
		SSLEngine sslEngine = sslContext.createSSLEngine();  //BAD: No endpointIdentificationAlgorithm set
	}

	{
		SSLContext sslContext = SSLContext.getInstance("TLS");
		final SSLSocketFactory socketFactory = sslContext.getSocketFactory();
		SSLSocket socket = (SSLSocket) socketFactory.createSocket("www.example.com", 443); 
		SSLParameters sslParameters = sslEngine.getSSLParameters();
		sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); //GOOD: Set a valid endpointIdentificationAlgorithm for SSL socket to trigger hostname verification
		socket.setSSLParameters(sslParameters);
	}

	{
		com.rabbitmq.client.ConnectionFactory connectionFactory = new com.rabbitmq.client.ConnectionFactory();
		connectionFactory.useSslProtocol();
		connectionFactory.enableHostnameVerification();  //GOOD: Enable hostname verification for rabbitmq ConnectionFactory
	}

	{
		com.rabbitmq.client.ConnectionFactory connectionFactory = new com.rabbitmq.client.ConnectionFactory();
		connectionFactory.useSslProtocol(); //BAD: Hostname verification for rabbitmq ConnectionFactory is not enabled
	}
}

References

  • © GitHub, Inc.
  • Terms
  • Privacy