Ignoring invalid SSL certificates on Cordova for Android and iOS

Written by JC Ivancevich

When developing mobile apps, it’s very common that we have to connect to web services or APIs which may be secure (https) but are still under development, so its SSL certificate is not valid or self-signed.

This would happen unless you want to spend a hundred bucks on a wildcard certificate for development environments.

For cases like the mentioned above it’s useful to be able to ignore errors generated by invalid certificates, so we can test the app, install it on any device, etc.

In order to get rid of this problem, the process changes depending on the platform we’re targeting.

iOS (Objective-C / Swift / Cordova)

iOS will always complain about invalid certificates, either in debug or release mode. To avoid this you should place the following code at the end of the AppDelegate.m file.

@implementation NSURLRequest(DataController)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
    return YES;
}
@end

For Cordova users this file is placed in

project/platforms/ios/Project/Classes/AppDelegate.m

Thanks to @machadogj for this one!


Android (Cordova specific)

In Android the history is different. It will allow you to make requests to services with invalid certificates, but only if the app is compiled in build mode. On the other hand, when you would build the app in release mode (ie: to send the APK to a co-worker or stuff like that), the Cordova Web View, which is where the HTML + CSS + JS you wrote runs, will not allow you to make “insecure” requests. Once again, to avoid this you should modify a platform file. In this case the file will be CordovaWebViewClient.java

You would need to modify a method in the mentioned filed, like this:

public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
  final String packageName = this.cordova.getActivity().getPackageName();
  final PackageManager pm = this.cordova.getActivity().getPackageManager();

  ApplicationInfo appInfo;
  try {
    appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
    if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
      // debug = true
      handler.proceed();
      return;
    } else {
      // debug = false
      // THIS IS WHAT YOU NEED TO CHANGE:
      // 1. COMMENT THIS LINE
      // super.onReceivedSslError(view, handler, error);
      // 2. ADD THESE TWO LINES
      // ---->
      handler.proceed();
      return;
      // <----
    }
  } catch (NameNotFoundException e) {
    // When it doubt, lock it out!
    super.onReceivedSslError(view, handler, error);
  }
}

This file is placed in (Cordova v4 and below)

project/platforms/android/CordovaLib/src/org/apache/cordova/CordovaWebViewClient.java

Update

In newer versions of Cordova (v5 and later) the file is now placed in

project/platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebViewClient.java

That’s all.

One thing I’d like to point at is that you should not use these solutions for production apps. This is just to test them or share them with co-workers.

If you have any comment feel free to drop me a line through the comments below.

Thanks for reading!