react-native-ssl-pinning icon indicating copy to clipboard operation
react-native-ssl-pinning copied to clipboard

disableAllSecurity does not work as expected on Android

Open biztems opened this issue 3 years ago • 1 comments

Hi @MaxToyberman

we have noticed that disableAllSecurity doesn't work as expected on Android.

On iOS it disables all checks, allowing self-signed certs without pinning - on Android it will still require pinning or it will error out. It is possible to completely disable checks using the following piece of code: https://rubyfaby.medium.com/how-to-ignore-ssl-for-react-native-f808810ffaed

Which I have already tested as working with the built-in fetch. It won't work with react-native-ssl-pinning as it is, since it creates a new OkHTTP client.

I have tried merging the code in OkHttpUtils.java, but I am getting a weird error, which I suppose is due to my unfamiliarity with Java.

Under public static OkHttpClient:

        if (defaultClient == null) {
            TrustManager[] trustAllCerts = new TrustManager[] {
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType)
                                throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType)
                                throws CertificateException {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[] {};
                        }
                    }
            };

            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);

            OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
            clientBuilder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            clientBuilder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            clientBuilder.cookieJar(cookieJar);

            if (BuildConfig.DEBUG) {
                clientBuilder.addInterceptor(logging);
            }

            defaultClient = clientBuilder.build();
        }

It just errors out like this when building:

OkHttpUtils.java:141: error: unreported exception NoSuchAlgorithmException; must be caught or declared to be thrown
            sslContext = SSLContext.getInstance("TLS");
                                               ^
OkHttpUtils.java:142: error: unreported exception KeyManagementException; must be caught or declared to be thrown
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
                           ^

From what I gather, there is some issue with the new X509TrustManager. Can'y really understand what is going wrong with it, though...

I was wondering if you could have a look at it? It would massively improve the usefulness of this lib.

Thanks!

Best Regards

biztems avatar May 10 '22 09:05 biztems

Looks like my code was almost correct - thanks to @ZacAdamsNavico for the correct implementation.

I have re-added the CookieJar support in a fork under our account.

https://github.com/biztems/react-native-ssl-pinning

biztems avatar May 27 '22 14:05 biztems