How to bypass SSL verification in Spring?
First of all, let me briefly inform you about Https. In computer networks, a message is created in the application layer and then transported to the destination by encapsulating the transport, network and link layer. In requests for Https, a request is sent from port 443 (not 80). After the server receives this request, it sends the SSL certificate including the public key to the client. The difference between Https and Http occurs in the next step. In the HTTPS request, logically the SSL/TLS layer occurs between the application and the transport layer, and the client encrypts the message to be sent by the public key in the certificate. Since the private key is on the server, the message content cannot be manipulated or read, even if the message is captured by any malicious software or user(MITM) until it exits the sender and goes to the server. Therefore, it is important that you have an SSL certificate at the relevant address when you are shopping or doing critical information.
Have you ever noticed that in the address section of the browsers, there is information about whether the sites are reliable? So according to what is such a classification? In fact, each organization can create a certificate that contains its own private key. In order to be considered as safe in the internet environment, they are certified by the Certificate Authority which has a reliable status in the world. In other words, the certificate produced by the organization is signed by a CA. After the SSL certificate is received after the Https request, the browser finds the CA part in the certificate. If this CA is listed in its list of trusted CAs, this certificate is trusted. If a site appears to be unsafe, even though it has SSL, its CA is not a recognized CA on the world.
There was a problem in the project I was working on. In one integration, the site that was requested could not be verified by JDK because it had an unreliable CA. In this case, we would either upload the certificates to JDK’s keystore/truststore or skip to verify the SSL. The DevOps team rejected the first option by saying that if the certificate changes, it will be done installing certificates manually, making management and tracking difficult. I’ve turned to the other option. (simple) I’ve found related stackoverflow answers 1 [2][2].
HttpsURLConnection.setHostnameVerifier(callback function that returns true if it matches the ip address of the request site)
But I’ve done the issue, I realized that it was still getting an error after getting version. When I did a little research in the project, I found two more locations using this method in configuration beans.
Now guess what’s the problem here?
1- If you look at the method, there is only a way to make a use in the style of (Class).(method). The method must be a static method. Here, SetHostnameVerifier is a static method. That is, this method is not the object variable, but the class variable. All objects created have a common value.
2- I said that the other places used are config beans. Beans are objects created by Spring Container. When spring runs, it starts to create objects with bean annotation.
So? As the beans that use this static method are created, they start to override each other. If the bean has been created for the last time, its setting remains. For the solution, I have defined a method with the @PostContruct annotation in the Application.java, which is the main entry point of the Spring Boot. I put setHostnameVerifiers here, removing all the config beans that use it. So the problem is solved.
The solution is simple, but it took me a while to understand the problem.