简体   繁体   中英

How to secure android app from network traffic capturing

My app is making some http requests and I don't want others to see the content of those requests. At the moment I can easily check what my app is doing by using Fiddler. Now in order to track network traffic on my phone I had to change my Wi-Fi settings and connect to the Internet using proxy server. ie my computer. Is it possible to programatically check whether phone is using proxy? If knew that phone is using proxy I would forbid user using the app by showing some error dialog. Are there any ways of solving this problem? I've seen apps that work on normal Wi-Fi settings but does not when using proxy therefore I assume there is a solution. By the way I'm using retrofit library for making requests.

Moving your traffic to use HTTPS will help protect it against network snoops like Fiddler.

However, Fiddler can decrypt HTTPS traffic with the user's help, which means that you can't only use HTTPS, you also need to implement Certificate Pinning, whereby the client code verifies that the server presented one specific certificate (not the interception certificate Fiddler generates).

However, even that doesn't really solve the problem, as the user can simply jailbreak their device and disable your certificate pinning code.

You should probably step back and reconsider what threats specifically you're trying to protect against and then update your question appropriately.

Programmatically check for a Proxy

Is it possible to programmatically check whether phone is using proxy?

Yes. Check the replies to this Stackoverflow anser.

If knew that phone is using proxy I would forbid user using the app by showing some error dialog.

Any code running on the client side can be manipulated at runtime by the attacker on a device he controls by using an instrumentation framework, for example Frida :

Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.

Possible Solutions

My app is making some http requests and I don't want others to see the content of those requests.

You've got yourself a difficult challenge here. Let's see some of your options...

Certificate Pinning

Several techniques exist to implement certificate pinning, but since Android API 24 it's supported natively via the network security config file. I have wrote the article Securing HTTPS with Certificate Pinning to show how it can be done:

In order to demonstrate how to use certificate pinning for protecting the https traffic between your mobile app and your API server, we will use the same Currency Converter Demo mobile app that I used in the previous article.

In this article we will learn what certificate pinning is, when to use it, how to implement it in an Android app, and how it can prevent a MitM attack.

Bypassing Certificate Pinning

Several methods exist, like with an instrumentation framework or by repacking the mobile app.

Bear in mind that just because certificate pinning can be bypassed it doesn't mean you shouldn't be using it in your mobile app, by the contrary it's strongly recommended that you do so.

Using an Instrumentation Framework

Unfortunately, Frida can also be used to bypass certificate pinning and I wrote the article How to Bypass Certificate Pinning with Frida on an Android App to show you how to do it:

Today I will show how to use the Frida instrumentation framework to hook into the mobile app at runtime and instrument the code in order to perform a successful MitM attack even when the mobile app has implemented certificate pinning.

Bypassing certificate pinning is not too hard, just a little laborious, and allows an attacker to understand in detail how a mobile app communicates with its API, and then use that same knowledge to automate attacks or build other services around it.

Using the a Repackaged Mobile App

Another techinque widely used is to repackage the mobile app without the code for certificate pinning or with it disabled. I wrote the article Bypassing Certificate Pinning that shows how to remove the network security config file and repackage the mobile app:

In this article you will learn how to repackage a mobile app in order to make it trust custom ssl certificates. This will allow us to bypass certificate pinning.

A Possible Better Solution

Are there any ways of solving this problem?

So, you already saw that certificate pinning is the way to go, but once it can be bypassed you need a way to detect this bypass in order to prevent this type of attack.

I recommend you to read this answer I gave to the question How to secure an API REST for mobile app? , especially the sections Hardening and Shielding the Mobile App , Securing the API Server and A Possible Better Solution .

Do You Want To Go The Extra Mile?

In any response to a security question I always like to reference the excellent work from the OWASP foundation.

For Mobile Apps

OWASP Mobile Security Project - Top 10 risks

The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.

OWASP - Mobile Security Testing Guide :

The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.

 public static boolean isNetworkConnected(final Context context) {
        boolean cks = false;
        final Activity activity = (Activity) context;
        ConnectivityManager connMgr = (ConnectivityManager) 
             context.getSystemService(Context.CONNECTIVITY_SERVICE);
        boolean isvpnConn = false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            for (Network network : connMgr.getAllNetworks()) {
                NetworkInfo networkInfo = connMgr.getNetworkInfo(network);
                if (networkInfo.getType() == ConnectivityManager.TYPE_VPN) {
                    isvpnConn |= networkInfo.isConnected();
                           AlertDialog.Builder alert = new 
                             AlertDialog.Builder(getActivity());
                                  alert.setMessage("Sonthing want wrong!! Please 
                        disconnect VPN and try again.")
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                          dialog.dismiss();
                            activity.finish();
                            activity.finishAffinity();
                    }
                }).setNegativeButton("Cancel", null);

        AlertDialog alert1 = alert.create();
        alert1.show();
                    cks = false;
                } else {
                    cks = true;
                }
            }
        }
        return connMgr.getActiveNetworkInfo() != null && connMgr.getActiveNetworkInfo().isConnected();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM