1

I am searching for 2 days for my problem and i had no luck in finding it.

my problem :

I have comodo ssl/tls certificate installed on my server, and I am using android volley library for connecting to server, until now i was using just "https://..." for my url and connecting via https connection to my server with no problem. but i recently installed "packet capture" android application on my phone, by default settings and a phone which is not rooted it cannot retrieve post/response information from my app to the server, but when you use a rooted phone, the packet capture app asks you to install a custom certificate on the phone so it can retrieve even ssl/tls connection, At first I though it's joking, but after installing the certificate it shows the whole information used in ssl connection to my server... I am so worried about the security of my app, which a hacker can use that capturing app to know what to send to my server and sets his coin number for example to 100000 :(

please show me a way to make my app's connection more secured . * I do'nt have a custom certificate installed on the app because the server certificate is trusted and working ok with the default use.

sorry for my poor English typing :)

Edit : thanks to @Ch4t4r for the idea... I did searched and find this for pinning the public key and it's so great, here is the github link : https://github.com/faruktoptas/volley-public-key-pinning

hope it helps others having the same problem

niafara
  • 13
  • 3
  • This looks like it doesn't have anything to do with SSL. The API of your server will alway be visible (more or less). Why can a simple request set the coin number? Maybe your server should authentificate/valide the requests. – jHilscher Sep 06 '17 at 10:48
  • @jHilscher actually it's not so simple, but i relied so hard on ssl for protecting communication, for example can you sniff instagram requests ? I need something like that – niafara Sep 06 '17 at 11:14

3 Answers3

2

The way that app works is as follows (summarized):

  1. Your app tries to establish a connection to your server
  2. The app captures the request and forwards it
  3. The app captures the answer from the server and replaces its certificate

It's a classic man-in-the-middle attack which works because the certificate of the app you are using is trusted. You cannot prevent rooted users from breaking your encryption.


The only thing you could do is security by obscurity. Try encoding your values (complementary values, or by encrypting them with a key stored in your app) or sending a hash of the entire request. This will lock most people out (the non-technical ones), but there is no absolute way of stopping users from cheating this way. What you could do as well is using one-time tokens (kind of how salts work) to encode your important values. Obfuscating your source code would help as well. But again, there is no absolute way, this is only laying stones in the way of users which might even be able to cheat. It significantly increases the time needed to figure out how to do so.

I wouldn't waste to much time on it, here's why:

  • About 20-25% of Android devices are rooted (according to some older data. I suppose it's actually less)
  • Some rooted devices are test or store devices (Kiosk mode); let that be 15% of all rooted devices
  • If 50% of the other rooted users know about the app (it won't be that high), we are down to 8.5% of all Android users
  • Using the security by obscurity principle only very tech-savvy users will be able to figure how to cheat. If that'd be true for 20% (again, that's a very high number) of all users which fit into the above we are at 1.7% of all Android users.
  • Considering that not all of those users might use your app, some might just not care, I would put the percentage of users which have the ability to cheat AND use your app to 0.5% at max.


A more drastic method would be blocking all rooted users.
Edit: As another answer suggests you could be using public-key pinning. Just remember that not all users tend to update as soon as you publish a new version effectively rendering your app useless if they don't. Thus it comes with a small risk.

Ch4t4r
  • 1,387
  • 1
  • 11
  • 30
  • thanks for your answer ch4t4r, the things you said is true, but if i am a hacker then i definitely have a rooted phone, although when I'm just a developer i have a rooted phone think what do a hacker have !!! , so don't you know if there is a way to force the volley use main and trusted certificates and not any other certificates ? I wonder if there is a way to just stop sending data while a not trusted app , vpn or certificate is installed ? – niafara Sep 06 '17 at 10:58
  • Again, you could block all rooted users. But believe me, no hacker will specifically target your app. My calculation is more or less accurate. If you want to hinder rooted users from cheating try the security by obscurity approach or by developing a smart algorithm which detects implausible scores. – Ch4t4r Sep 06 '17 at 11:02
  • i edited my comment above, yes i can recognize them but its the second target, first i want to stop this ... you know i just opened that "packet capture" app then tried to sniff instagram, then instagram got failed and nothing showed in the capturing packet app... you know i want something like this – niafara Sep 06 '17 at 11:08
  • Ahh, well I could have told you about public key pinning if you could have told that before. – Ch4t4r Sep 06 '17 at 11:27
  • public key pinning is the great solution ... i did researched and solved it, thank you very much... although by renewing the ssl certificate from comodo i don't think ever needs to change the key... – niafara Sep 06 '17 at 11:55
  • The important fact is that the public key stays the same. It would be new to me that you can just renew the notAfter field of a certificate but if comodo states so it has to be. – Ch4t4r Sep 06 '17 at 12:31
  • Yea I know what you mean ... since yesterday i was thinking about a way to not get stucked with this public key ... so I found a way for when the ssl public key got changed, at first when app started, it just to a simple post request to fetch public key from the server, and store the value just in a application private variable, later on while the app applicatin class not closes, it will use the same public code... so if public key changed on server, nothing needs to be changed in the app ... and users just should restart the app. – niafara Sep 07 '17 at 12:22
  • That's an attack vector again. If you store the public key your app will verify your server against in the private storage root users can access it again. Try this: sign the public key you download with a self-generated certificate (with a very long lifetime) and store that public key in your code. Then check if the downloaded public key was tampered with. That way users cannot replace the downloaded file because only you can sign it. – Ch4t4r Sep 07 '17 at 12:49
  • Actually i think right now it's pretty secured... the app just do a tls handshake if a outside certificate is installed and returns false... the parameter of public key is also secured in the application class ... so it's almost secured ok for now... – niafara Sep 08 '17 at 13:37
  • Oh i just love talking about these stuff to someone that can undrestand it ... since i'm working alone and all of my classmates have no idea about our major at all!!! Thank you so much ... – niafara Sep 08 '17 at 13:41
  • Well, you can find a lot of skilled people here at stackoverflow. And this topic here is kind of only scratching the surface. But in general you are right, not everyone out there understand this level of complexity, today's students only learn how to do something, not why and how to expand it. This affects everyone - including myself. I just happen to be somewhat profound in this topic because I'm an Android developer, visited quite a few cryptography and IT security lectures and have been doing IT since ~9 years now. – Ch4t4r Sep 08 '17 at 20:26
  • that's exactly what i mean... for the past couple years i was just reading the questions here , from now on i try to answer some question which i do know the solution, by the hope of getting help later by someone like you dear @Ch4t4r – niafara Sep 09 '17 at 08:53
1

I am not sure what programming language your app is written in but you can look into certificate pinning to prevent these attacks. Your code would check the SSL certificate prior to sending any request and if the values don't match you can have your app fail with an error message.

https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning

  • that's exactly what i'm looking for, I'm writing an android app using android studio with java language... can you give me some code in java for checking ssl certificate like what you said? – niafara Sep 06 '17 at 11:11
1

There is a java library on github that has some examples.

https://github.com/Flowdalic/java-pinning/blob/master/README.md