Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Android phone from connecting to WiFi network unless my app approves it?

I want to develop an app that can prevent connection to a WiFi network unless I approve it. I want to be able to query the MAC address of the access point and compare that to a list of known addresses corresponding to SSIDs. The goal of the app is to protect users from accidentally connecting to malicious access points, such as the types that can be produced with pineapple devices.

I'm not clear from my research how I would achieve this goal. Questions such as How to be notified on wifi network status change? explain how to detect the connection has happened, but for my use case that's already too late.

Neither ConnectivityManager nor WifiManager seem to offer methods for adding listeners that could interrupt a connection in progress.

Some thoughts I've had for a solution:

  • Install myself as a proxy and make the decision as to whether to allow data through. However, this doesn't seem to be an option based on Do Android proxy settings apply to all apps on the device? (hint: the answer is "No").

  • Replace the existing WiFi manager with something of my own creation. However, I've really struggled to find any information in the Android developer guides regarding replacing system components. Consequently, I'm not sure this is possible on non-rooted phones.

  • Store the network passwords within my app and set the passwords in the WiFi manager to nonsense values. Then capture a broadcast message that warns of a failed connection (presumably something like WifiManager.WPS_AUTH_FAILURE) and selectively decide to reconnect back to that network. Might be a possible (if ugly) solution, but can I set the password back to a nonsense value while the network is still connected, to ensure we don't quietly connect to another SSID of the same name? I'm not sure. It occurs to me that pineapple devices would probably accept any password, thus rendering this approach void.

  • Find some way to prevent Android automatically connecting to known networks (i.e. networks that have been used before or have a password stored with them). Then I could manage all connections/disconnections from my app. I can't see how to do this manually on my phone, however, so I'm doubtful this is possible programmatically.

Can anyone suggest an approach that would work on a non-rooted phone?

like image 677
Duncan Jones Avatar asked Nov 01 '14 07:11

Duncan Jones


People also ask

How do I stop my Android from automatically connecting to Wi-Fi?

To stop your Android device from auto-connecting to open networks, open the settings and go to Network & Internet > Wi-Fi > Wi-Fi preferences. Tap the button next to Connect to open networks to disable it.

How do I get my phone to stop connecting to random Wifis?

Android: Go to Settings > Network & Internet > Wi-Fi > Wi-Fi preferences. Toggle off Connect to public networks.

Can you prioritize Wi-Fi connections on Android?

Prioritize Android Wi-Fi Network Using Built-In Settings To check if your ROM has one, open Settings > Network & internet > Wi-Fi. Tap on the overflow menu, then hit Advanced Wi-Fi. If you see a Wi-Fi Priority option, you can specify the priority of Wi-Fi networks here.

How do I Stop my Android from automatically connecting to Wi-Fi?

To stop your Android device from auto-connecting to open networks, open the settings and go to Network & Internet > Wi-Fi > Wi-Fi preferences. Tap the button next to Connect to open networks to disable it.

Why is my Android 11 not connecting to Wi-Fi?

Whatever the reason might be, Android 11 will let you disable automatically connecting to specific networks. Android 11 has a new toggle in the settings panel for Wi-Fi networks called 'Auto-connect,' and when it is switched off, your device won't automatically connect to the given network as soon as it is discovered.

Is your Android device connecting to WiFi without you knowing?

But, as convenient as connecting to a nearby WiFi may be, it can also be dangerous. Without you knowing, your phone could detect a nearby free WiFi network (that is not safe) and connect automatically. So, if you don’t mind switching over manually, here how you can stop your Android device from doing it on its own.

How to block Internet access to an app on Android?

The first method to block internet access to an app starts by opening Settings and going to Mobile network. In the Android Mobile network settings, tap on Data usage. Next, tap on Network access. Now you see a list of all your installed apps and checkmarks for their access to mobile data and Wi-Fi.


2 Answers

You can't implement a very robust system without rooting the device. Here's the closest you can get, I think:

  1. Use getConfiguredNetworks() to fetch a list of networks currently configured on the user's device
  2. For each WifiConfiguration in the list, set the public field BSSID to the desired "safe" MAC address
  3. Call saveConfiguration() to persist the changes

Alternatively for step (2.), you could call disableNetwork() for each configured network, and selectively enabled them based on the BSSID. Note that MAC addresses can still be spoofed fairly easily.

like image 171
JstnPwll Avatar answered Sep 21 '22 07:09

JstnPwll


you can listen to connectivity change of wifi and act on that events to enable disable wifi

private ConnectivityManager connectionManager;
boolean previousConnectivityStatus;
private WifiManager wifiManager;

/* Register Connectivity Receiver */
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
context.registerReceiver(networkBroadcastReceiver, intentFilter);

/* Register Wifi State Listener */
IntentFilter wifiStateIntentFilter = new IntentFilter();
wifiStateIntentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
context.registerReceiver(wifiStateReceiver, wifiStateIntentFilter);

connectionManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

private BroadcastReceiver wifiStateReceiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        Utility.traceM("NetworkController.wifiStateReceiver.new BroadcastReceiver() {...}::onReceive");
        int extraWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
        switch (extraWifiState)
            {
            case WifiManager.WIFI_STATE_DISABLED:
                {
                    Utility.trace("Broadcast Wifi State Disabled");
                    if(isWifiStateEventsEnabled)
                    {
                        EventBus.getDefault().post(new NetworkEvent(NetworkEventType.WIFI_DISABLED));
                    }
                    break;
                }
            case WifiManager.WIFI_STATE_ENABLED:
                {
                    Utility.trace("Broadcast Wifi State Enabled");
                    if(isWifiStateEventsEnabled)
                    {
                        EventBus.getDefault().post(new NetworkEvent(NetworkEventType.WIFI_ENABLED));
                    }
                    break;
                }
            }
    }
};

private BroadcastReceiver networkBroadcastReceiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        Utility.traceM("NetworkController.networkBroadcastReceiver.new BroadcastReceiver() {...}::onReceive");
        boolean connectivityStatus = isInternetConnectivityAvailable();
        if (previousConnectivityStatus != connectivityStatus)
        {
            if (connectivityStatus)
            {
                previousConnectivityStatus = true;
                Utility.trace("Broadcast Internet Available");
                EventBus.getDefault().post(new NetworkEvent(NetworkEventType.INTERNET_CONNECTED));
            }
            else
            {
                previousConnectivityStatus = false;
                Utility.trace("Broadcast Internet Disconnected");
                EventBus.getDefault().post(new NetworkEvent(NetworkEventType.INTERNET_DISCONNECTED));
            }
        }
    }
};
like image 28
Kirtan Avatar answered Sep 25 '22 07:09

Kirtan