SSL on Cordova and prevent man in the middle attack

I’m making a app. This app communicate with a API, and I would like to be this communication a secure communication. (The code I post here is in pure cordova because that’s easy)

Some background information

  • My API has a SSL Certificate created by letsencrypt.
  • In my app I’m useing the cordova-plugin-advanced-http
  • To check the trafic between the app and the api I use Packet Capture link
  • Only working for android

Want do I want

  • Encrypted traffic
  • Prevent man in the middle attack ( If this has been detected, there will be no traffic)
  • If I look at Packet Capture log’s I don’t wanna find any information

What did I tryed

  1. try the ssl link =
    cordova.plugin.http.sendRequest('https://domain.tk/API/some/endport/', function(response) {
        // prints 200
    }, function(response) {
        // prints 403
    })

Data is not encrypted , I can see everything in Packet Capture

  1. Made a CER file, put it in my project and pinned my connection
cordova.plugin.http.setServerTrustMode('pinned', function(e) {
        console.log('success!');
    }, function() {
        console.log('error :(');
    });

When I starting Packet Capture TLS is not established (so no data find in Packet Capture). When I Packet Capture doesn’t running traffic is working fine (GREAT)

Problem

The pinned methode is working “fine” the problem is if my certificat will be renewal , I always have to update my CER file in my app, and this is the problem. I’m not able to find the solution by myself.

I talked to the support of my host, and I can’t see the details in there certbot (for the --reuse-key option link).

Can anyone give me tips for a encrypted traffic, that prevent man in the middle attack in a cordova app? Thanks !

1 Like

Hey there,

in our App we implement this exactly like you. Of course you have to renew the Certificate after a few years. That’s normal. We solved it by creating a REST endpoint which returns the min Version that is required to work with the current Backend:

{
    "android": "1.2.0",
    "ios": "1.1.15"
}

This Values van be changed in our admin console, so when a new certificate is needed, build a new app version with it and update the minVersion in Database.

When you implement like this, you first have to check the min version on app start up and then, if successfully, enable SSL-Pinning, the way you do.

1 Like

Hey,

Thanks for answering this question.
If I understand this correcty you do replace the CER file in the app ?

Yeah, but in a normal App Release. Of course you can change the CER File and build a new Version for the App Stores. To not run the “old” App into unhandled Errors, we include the minVersionCheck

Yeah, but I’m looking for a other option. If I need to change this for all my app’s It will take a lot off time. I’m looking for download the CER file or just a complete other methode

I think you can also test Code Push, as the Certificate only has to be in the /www* Folder. With this Plugin you can perform an In-App-Update. You can test to change the certificate within the Update too.

Hello there,

Thank you for the support, I tested it but I only can only do code update’s.
Do I miss something ?

I would like to back up a moment. I get that certificate pinning deals with the problems of rogue CAs, but LetsEncrypt isn’t a rogue CA. Why can’t you just use ordinary Angular HttpClient here?

Here’s where things start to get weird and/or ironic, because:

…which on the documentation page you linked says:

SSL decryption using man-in-the-middle technique

So you’ve deliberately injected a MitM into your connection. It’s no wonder that:

…but I’m not clear on how that indicates that:

…because it looks to me like Packet Capture is decrypting it. Any blackhat sitting between your device and the backend should see encrypted traffic. Try running Wireshark or something similar upstream to check.

Now, if your definition of “MitM” includes stuff that the owner of the device running your app is deliberately doing, I’m going to argue that that’s an overly broad and therefore not very useful definition. There is absolutely nothing you can do to prevent somebody with a copy of your app binary sniffing data that they are sending from your app. They could always run your app on an emulator or rooted device.

I used Code push in an old App, so i don’t know exactly, bit i can remember we also change assets and i think the certificate counts as one, but maybe i’m wrong :thinking: