I'm looking for a solution similar to this answer, but much safer. I'd like to disable the certificate validation, but for a single request only (which is all I need). So it should do one or more of the following
- return to the secure state when the one request is done
- disable validation for the given URL only
- (maybe) use the insecure settings just for one thread
Addendum
I really wonder what's wrong with this question (score -2) when compared to the original one (score +46), when I'm asking for a more secure solution. Could someone explain?
To explain why I need this: There's a valid server certificate and normally, it gets used. But I need to send one request to localhost
and it has to work on a developer machine, too. It must be https
as there's no http
support.
The solution
This utility class is based on provided example. Uses a 'relaxed' SSLContext which preconfigures a TrustManager accepting all certificates. Also is needed a hostname verifier in case your localhost ssl certificate was issued to a different CN
Apply it to each connection that requires a 'relaxed' ssl verification using
HttpsURLConnection.setSocketFactory
andHttpsURLConnection.setHostnameVerifier
. The default behaviour wont be changedUse it in this way
Example1 (default)
Example2 (bad hostname)
Example3 (chain not in default truststore)
The context
I think your question is on-topic, useful and well expressed. In some scenarios is suitable, or rather, is not essential to apply a context of high security. plain HTTP is still being used...
Let's analyze your context. The required is access to localhost through HTTPS without trusting in server identity. It means that you want to accept any certificate presented by the server. The security issue with this scenario is a MITM attach (man in the middle). From (wikipedia)
But is it possible a MITM attack with an untrusted https connection to localhost?
See https://security.stackexchange.com/questions/8145/does-https-prevent-man-in-the-middle-attacks-by-proxy-server/8309#8309
First, in https the server has to present the server certificate to the client. The client validates the public key of the certificate and check that matches with local truststore. With the colaboration of the net administrator it would be possible to sniff the net and set a proxy to intercept the connection. But the malicious proxy is not in the possession of the matching private key so the proxy server may try to forge the certificate and provide his own public key instead. The certificate will not be present on client trustore, so the connection will be rejected,. But if you remove the truststore verification, the attack is theoretically possible.
But, is MITM possible restricting connections to localhost?
See https://security.stackexchange.com/questions/61399/are-mitm-attacks-possible-on-http-loopbacks
In the general case it is not possible, but an attacker with root access to the machine could alter DNS and redirect requests to the malicious proxy. Even using 127.0.0.1 it could be possible if the application has a way to configure the connection port.
The paranoic solution could be hardcode the server connection url, port and even trustore. But you are talking about localhost on a development environment, so I think we can relax a little
Just use instance methods
setX()
instead of staticsetDefaultX()
:The solution to this is always to either import the server certificate into the client truststore or else, and better, get the server certificate signed by a trusted CA, if it's under your control. You can't do it safely in code, and you shouldn't want to 'just for development'. Otherwise you're not testing the production code in development.