Android prevent man-in-the middle attack for SSL - android

I'm using HTTPS in my Android app to communicate with my own API.
When I packet sniff, I don't see any information which is good.
However, when I use software like Fiddler2 to install a trusted certificate on my Android, I can see all my HTTPS calls in the clear which is dangerous.
The problem is so close to this guy but in Android not iPhone:
hiding iOS HTTPS calls from fiddler
I am using loopj library to make my https calls: Android Asynchronous Http Client
http://loopj.com/android-async-http/
How can I deal with such a vulnerability ?? ( I know how to deal with it conceptually but I need example code )

When the user chooses to install Fiddler2's certificate as a trusted root certificate, he is then choosing to compromise his own security. I'm not sure there's much you can do about it, since your application's HTTPS connexion will go through Android's certificate validation system, which will consider the connexion as valid, since the certificated is trusted.
The solution I would go for is embedding your SSL certificate in your application, and tell your application it is the only trusted certificate. It's secure and free, as you can attach a self-signed certificate you created yourself, since you control the verification mechanism. See this blog article for code example.

Related

Android App Retrofit Web Service Request Intercept and Modify Using Burp Suit Attack Fix

In my Android App we are using retrofit web service for communication to server. Some Hacker intercept request and modify it using some tool Burp Suit.
Please help me to let me know how I stop Intercept Attack.
What Burp Suit does - it basically performs a Man-in-the-middle attack. It generates an HTTPS certificate and pretends to be a browser.
The thing is if your server and your client are protected from this MITM attack - those tools won't work. At least in the mobile apps - the browser will show a security error but still will pass the data through.
The solution you can use is including your specific SSL certificate into the app and making the app consider it to be the only trusted one. It will be more or less secure - depending on the implementation. It is also free because you can attach a self-signed certificate you created yourself since you control the verification. Naturally, the backend should also use the same SSL certificate. While using this technique Burp Suit generated certificates won't work because the app knows only one trusted certificate.
The technique itself is called SSL pinning or certificate pinning and you can find plenty of info online about how to implement it both on the client and server.
I will give you several links though:
Here is the nice article about how to do it with retrofit(okhttp).
Here is the official documentation for OkHttp CertificatePinner
Here is the small implementation of retrofit SSL pinning.
Here is one more article.
It is not enough but the issue is complex and one StackOverflow answer won't suffice. But I think it is a good start to do the actual implementation.
Also as a small recommendation - use encryption to store your SSL certificate key instead of plain string storage - it still won't be secure from memory spoofing but it will be much harder for the hacker to use it.

Certificate pinning and SSL

I am trying to learn about making secure mobile applications. I am curious to know, do we need Certificate pinning if our network calls from mobile to server use https ?
Yes, you should save it as a raw file in the folder of your app and use it to call the server for the requests.
Pay attention, if you have a self signed certificate you should force it as made by trusted authority.
I am curious to know, do we need Certificate pinning if our network calls from mobile to server use https ?
https guarantees that the data in transit between your mobile app and API server is encrypted and cannot be spied on by third parties, thus partially preventing it against Man in the Middle attacks.
So I say partially because an attacker can induce users to install a custom ssl certificate in order for them to use a free wifi. This is usually done with fake wifi captive portals where you have to sign in in order to have free wifi, like the ones you found in airports, trains, etc. If an attacker succeeds in tricking the user then all the traffic is routed through the attackers computer and despite being https it can be decrypted once the mobile app is using the attackers custom certificate, but the attacker will always use the original certificate when communicating with the API server, thus neither the API, server, mobile app or the user are aware that the communication is being intercepted and maybe even tampered with.
So using certificate pinning will prevent any type of a Man in Middle Attack to occur, even the ones where the user of the mobile app is the attacker that intentionally decrypts is own traffic in order to reverse engineer the mobile app communication with the API server in order to gain enough knowledge to mount an attack against it.
Now is time for the bad news... Certificate pinning can be bypassed when the attacker as access or controls the mobile device. This article walks you through on how certificate pinning can be used and bypassed by using a framework like xPosed, that will intercept the calls to validate the certificate, thus bypassing the validation process.
So should I use certificate pinning? Yes you should, because is one more layer of defence and requires more effort for an attacker to reverse engineer your mobile app, that he may deem not be worthy the effort, but if he deems worthy the effort then you may want to search in google for a Mobile App Attestation solution to protect further the communication between the mobile app and the API server.
But keep in mind that while certificate pinning may be easy to implement in your mobile app it may be an operational nightmare to maintain. Be sure to read the section PINNING IS A NIGHTMARE in the link I referenced previously about bypassing certificate pinning.
Edit
You can read the article Steal that API Key with a Man in the Middle Attack to see a practical example on how a secret can be extracted from a https request sent from a mobile app to the backend API, by performing a MitM attack.
So, in this article you will learn how to setup and run a MitM attack to intercept https traffic in a mobile device under your control, so that you can steal the API key. Finally, you will see at a high level how MitM attacks can be mitigated.
While we can use advanced techniques, like JNI/NDK, to hide the API key in the mobile app code, it will not impede someone from performing a MitM attack in order to steal the API key. In fact a MitM attack is easy to the point that it can even be achieved by non developers.
Afterwards you can also take a look to the article Securing HTTPS with Certificate Pinning on Android to understand how you can implement certificate pinning to prevent a MitM attack.
In this article you have learned that certificate pinning is the act of associating a domain name with their expected X.509 certificate, and that this is necessary to protect trust based assumptions in the certificate chain. Mistakenly issued or compromised certificates are a threat, and it is also necessary to protect the mobile app against their use in hostile environments like public wifis, or against DNS Hijacking attacks.
You also learned that certificate pinning should be used anytime you deal with Personal Identifiable Information or any other sensitive data, otherwise the communication channel between the mobile app and the API server can be inspected, modified or redirected by an attacker.
Finally you learned how to prevent MitM attacks with the implementation of certificate pinning in an Android app that makes use of a network security config file for modern Android devices, and later by using TrustKit package which supports certificate pinning for both modern and old devices.
I hope that both articles have made more clear why certificate pinning is recommended to be used to secure https connections from prying eyes.
EDIT 2
If you want to implement certificate pinning but are afraid of making any mistake while creating the network_security_config.xml configuration file then just use this free Mobile Certificate Pinning Generator to create it for you:
and it will give you a network_security_config.xml configuration file ready to be copy pasted:

Will Self Sign Certificate work while publishing to chrome cast?

Developing a simple android application that will cast a URL (webpage) on bigger display.
For publishing "the receiver app must be served over SSL (HTTPS)". For that I have generated self-signed SSL Certificate and plan to use the same.
URL for publish
However, On trying to access the page from browser, it gives following warning:
The site's security certificate is not trusted! You attempted to reach
basilapps.com, but the server presented a certificate issued by an
entity that is not trusted by your computer's operating system. This
may mean that the server has generated its own security credentials,
which Chrome cannot rely on for identity information, or an attacker
may be trying to intercept your communications.
So my query is:
(A) Will self-signed certificate will work fine during publishing?
(B) If not, then do I need to purchase SSL certificate from trusted authority?
(C) Are there freely available trusted certificates services available?
Thanks
Self-signed certs do not work and yes, you need to get/use a trusted one form a known authority. If you can use App Engine, that works since it already has that. For development, either use http or use App Engine or even Google Drive (the last two support https).

Security issue, HMAC in header vs https, or both?

I'm setting up a server which an android app and an iPhone app will connect to. And I'm wondering what type of security is more secure for sending/requesting data?
Currently I generate a HMAC-SHA256 of the content I'm sending to the server in the header to verify its integrity.
But I'm wondering if its more secure to use a https connection instead? If I use https, could I skip the HMAC?
I would like to know the differences in security, which is more secure?
And also, if I'm using either is it better to use both for an extra layer of security?
Quick answer to your questions: SSL if used properly should give you more security guarantees than HMAC. So, usually SSL can be used in a way that removes the need for HMAC.
HMAC provides integrity as well as authenticity. Assuming the client and the server use pre-shared symmetric keys to calculate the HMACs, one side can be sure that the device on the other end has the secret key. This provides authenticity of both server and client.
What is missing in this picture (with just HMAC) is confidentiality. What is the nature of data exchanged between the server and client? Is there any sensitive user data being transferred during the communication that you don't want a man-in-the-middle to see? If so, then you may want to use SSL.
SSL gives you confidentiality (among other things). Meaning that you can be sure that you have a secured end-to-end connection and no man-in-the-middle can see what data is being exchanged between the server and client. However, common SSL usage does not include client machine authentication. Fro example, your web browser checks for Paypal's authenticity when you go to their https webpage. But the Paypal server does not ask your browser to send any certificate from your side.
Since you are comparing SSL with HMAC, I am assuming you care about authenticity of both sides. So, use SSL with both server and client authentication. This basically means that both of them would ask for each other's certificates and check different aspects of the certificates (i.e. common name, certificate issuer etc.). You can create your own certificate issuer to sign these certificates.
If you are making an app for AppStore or Google Play that users can simply install and start using, you may want to think through how the client side certificates will be generated, signed or who will sign them. You can remove the need for client side certificate (and signing) by adopting a model similar to GitHub's, where the user manually informs the server of trusted public keys to authenticate devices. But you can probably see how this process might not be user friendly.

Securing a web service so it can only be called by a specific Android application

We have a web service that should only be called by a specific Android app. What solutions are there for this problem?
The requirement is to not use authentication at all.
If it's only your client and your server, you can (and should) use SSL without purchasing anything. You control the server and the client, so each should only trust one certificate, the one belonging to the other and you don't need CAs for this purpose.
Here's the high-level approach. Create a self-signed server SSL certificate and deploy on your web server. You can use the keytool included with the Android SDK for this purpose. Then create a self-signed client and deploy that within your application in a custom keystore included in your application as a resource (keytool will generate this as well). Configure the server to require client-side SSL authentication and to only accept the client certificate you generated. Configure the client to use that client-side certificate to identify itself and only accept the one server-side certificate you installed on your server for that part of it.
A step-by-step for this is a much longer answer than is warranted here. I would suggest doing this in stages as there are resources on the web about how to deal with self-signed SSL certificate in Android, both server and client side. There is also a complete walk-through in my book, Application Security for the Android Platform, published by O'Reilly.
You'll normally store that certificate/private-key in a keystore of sometype (a KeyStore if you're using Android) and that keystore will be encrypted. That encryption is based on a password, so you'll either need to (1) store that password in your client somewhere, or (2) ask the user for the password when they start your client app. What you need to do depends on your usecase. If (2) is acceptable, then you've protected your credential against reverse engineering since it will be encrypted and the password will not be stored anywhere (but the user will need to type it in everytime). If you do (1), then someone will be able to reverse engineer your client, get the password, get the keystore, decrypt the private key and certificate, and create another client that will be able to connect to the server.
There is nothing you can do to prevent this; you can make reverse engineering your code harder (by obfuscation, etc) but you cannot make it impossible. You need to determine what the risk you are trying to mitigate with these approaches is and how much work is worth doing to mitigate it.
I guess this will work with proper authentification in place. First post I just stumpled upon was this one:
Securing communication from android to a web service
Hope it helps =)
If you're absolutely certain this web service will only need to be accessed by authorized applications/devices, go with client-side SSL certificates and restrict access at the server to only clients with authorized certs. This has the bonus feature of forcing SSL at all times so you don't like auth secrets over an open channel. Here's a quick guide for Apache, but you could use nginx too:
http://it.toolbox.com/blogs/securitymonkey/howto-securing-a-website-with-client-ssl-certificates-11500

Categories

Resources