Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature request] Block Internet access per app #7549

Open
3 of 10 tasks
denosaurtrain opened this issue Jan 30, 2025 · 7 comments
Open
3 of 10 tasks

[Feature request] Block Internet access per app #7549

denosaurtrain opened this issue Jan 30, 2025 · 7 comments
Labels
Android Issues related to Android feature request For issues asking for new features

Comments

@denosaurtrain
Copy link

denosaurtrain commented Jan 30, 2025

I have checked if others have suggested this already

  • I have checked this issue tracker to see if others have reported similar issues.

Feature description

tl;dr

As an Android user, I would like a way to fully block Internet access for specific apps, so that I can prevent those apps from uploading my personal data.

the problem

In 2025, Android app permissions are still very limited. There is no way to block apps from accessing the Internet, which is especially concerning since apps can collect a lot of user data even with no special permissions or user interaction.

a possible solution

I trust Mullvad, and Mullvad already protects various other parts of my web traffic like DNS, etc. Ideally, Mullvad would provide an option for blocking specific apps from accessing the Internet.

As a dev I figure the easiest approach would be to add this feature inside the split tunneling UI. For example, in addition to the + button for each app, there could be a option, which sticks the app into a separate "Blocked Apps" list. (I'm not UI designer; maybe that's a terrible idea!)

In terms of how to block, I am making the uneducated assumption that the split tunneling logic can be "easily" modified to block apps rather than direct them to Mullvad. If nothing else, direct them to a black hole? IDK.

misc

This feature is more of a "firewall" thing than a "VPN" thing, so I understand if you fine folks feel that it is out of scope for Mullvad.

Here's a barely related feature request: #3263

Alternative solutions

Admittedly, this should be a permission built into Android itself, but sadly Google has stated (I forget where) that they will not implement it — presumably because they need ads and ads need Internet.

There are some apps out there which claim to offer a no-root app-level firewall. However, I don't know if I can trust them... I would much prefer to use an MVP version of this feature from Mullvad rather than a more full-featured version from some other provider. Edit: I tried NetGuard (5M+ downloads) but it uses the Android VPN service, which means I can either have a firewall or a VPN but not both.

I'm open to building my own APK if there's an open source Android firewall out there.

Type of feature

  • Better privacy/anonymity
  • Better at circumventing censorship
  • Easier to use
  • Other

Operating System

  • Android
  • iOS
  • Windows
  • macOS
  • Linux
@denosaurtrain denosaurtrain added the feature request For issues asking for new features label Jan 30, 2025
@denosaurtrain
Copy link
Author

denosaurtrain commented Jan 31, 2025

I spent some time spelunking the code (for the ~first time), hoping that I could contribute this feature on my own. In the end, I have some theories about the blockers for implementing both this feature and the most requested Mullvad feature:

Conceptually, the tunneling interface consists of an allowlist of apps to "split". That model/API gets expressed in a number of places, such as the UI and GRPC service, but here's a clean example:

#[cfg(any(windows, target_os = "android", target_os = "macos"))]
#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq)]
pub struct SplitTunnelSettings {
/// Toggles split tunneling on or off
pub enable_exclusions: bool,
/// Set of applications to exclude from the tunnel.
pub apps: HashSet<SplitApp>,
}
/// An application whose traffic should be excluded from any active tunnel.
#[cfg(any(windows, target_os = "macos"))]
#[derive(Debug, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct SplitApp(std::path::PathBuf);
/// An application whose traffic should be excluded from any active tunnel.
#[cfg(target_os = "android")]
#[derive(Debug, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub struct SplitApp(String);

My first thought was to change SplitApp to AppRule, which would open up some flexibility for use cases like mine. However, that doesn't address the problem of split tunneling rules for processes which has an entirely separate interface with similar add/remove/clear methods and such (add_split_tunnel_process).

To address both apps+processes and #7549+#2808, my gut says to consolidate those into a CRUD interface on TrafficRules, which might look vaguely like this (and written in Protobuf):

pub struct SplitTunnelingSettings { 
  /// Whether to enable the split tunneling subsystems
  /// When disabled, all traffic goes through the VPN
  pub enable: bool,
  /// The action to apply if no matching rules are found
  /// For example, selects whether,
  /// - to use VPN selectively for a few apps, or
  /// - to use VPN for all except a few apps, or
  /// - to enter lockdown mode
  pub default_action: TrafficAction,
  /// List of rules/exceptions to the default
  pub rules: Vec<TrafficRule>, 
}


struct TrafficRule {
  source: TrafficSource,
  action: TrafficAction,
  // someday could include destination rules?
} // for future proofing, should this be an enum? IDK

enum TrafficSource {
  App,
  Process,
}

enum TrafficAction {
  /// Block all network access
  Block,
  /// Exclude this traffic from the VPN
  BypassTunnel,
  /// Always send this traffic through the VPN
  RequireTunnel,
}

Sadly, I won't have time to contribute a change that big anytime soon. At this point I'm merely sharing my findings and proposing a possible solution.

@banished-oracle
Copy link

In 2025, Android app permissions are still very limited. There is no way to block apps from accessing the Internet

there actually is with the android.permission.INTERNETpermission its just not exposed in most android versions installed by default on devices. Some AOSP forks expose that permission such as GrapehenOS.

@albin-mullvad albin-mullvad added the Android Issues related to Android label Feb 3, 2025
@Pururun
Copy link
Contributor

Pururun commented Feb 18, 2025

@denosaurtrain Thanks for the feature request!

I am not 100% sure it is possible. As far as I know it is possible leak/block traffic from certain apps using the addDisallowedApplication/addAllowedApplication feature when setting up the tunnel. So in the Mullvad app if you set enable an app in the split tunneling feature that app will be added to the disallowedApplication list when setting up the tunnel.

It is also possible, and this is afaik what most firewall apps on android does, to add one or more apps to the allowedApplication list. This will cause the traffic of only these apps to go through the tunnel. This traffic then gets dropped and these apps can not reach the internet.

Now to my knowledge there is no way to combine these two features, but if I am missing something or if you have a good idea I am all ears.

@denosaurtrain
Copy link
Author

It is also possible, and this is afaik what most firewall apps on android does, to add one or more apps to the allowedApplication list.

I'm not sure about other apps, but Netguard (a popular, open source firewall) uses a different approach. Rather than relying on Android to decide which apps to allow, Netguard does the packet filtering itself. From what I can tell, Netguard:

  1. Gets the uid for a given network connection
  2. Gets the application/package name for that uid
  3. Checks whether that app is one that should be blocked
  4. If yes, it drops the packet or responds with a protocol-specific response that indicates failure

Refs

Sadly, that approach requires much more effort than the allowedApplication approach, but like you said the easy option doesn't quite do what we want.

On the plus side, adding packet filter middleware to Mullvad would enable many other features like tracking network stats per app; showing users which apps are connecting to which upstream services; inspecting packets per connection; and the most requested feature,

When I opened the issue, I had hoped it would be easier to implement. Gven the work that seems to be required, I'm under no illusion that this feature will be implemented any time soon (if ever).

@Pururun
Copy link
Contributor

Pururun commented Feb 20, 2025

@denosaurtrain

Thanks for the great explanation. You learn something every day. :)

On the plus side, adding packet filter middleware to Mullvad would enable many other features like tracking network stats per app; showing users which apps are connecting to which upstream services; inspecting packets per connection; and the most requested feature,

I agree that this all sounds very interesting, however it kinda makes the Mullvad app more into being, like you noted, a firewall app and that is not really our goal at the moment. Which leads to this:

When I opened the issue, I had hoped it would be easier to implement. Gven the work that seems to be required, I'm under no illusion that this feature will be implemented any time soon (if ever).

And as you this requires a lot of work, which we would rather spend on doing things to improve the VPN part of the app.

But still any ideas and feedback is appreciated. :)

Of course in an ideal world there would be a way to combine Netguard with Mullvad and use both apps at the same time.

@Ammako
Copy link

Ammako commented Mar 6, 2025

For what it's worth, per-app internet toggles are trivially bypassed by just sharing data to another app (via inter-process communications) which does have internet access.

It's not necessarily clear if any tracking or analytics actually does use IPC to bypass per-app internet restrictions right now, but even if they don't currently do it, it's a possibility, and they could start doing it one day without warning. So if your threat model needs you to make sure certain apps cannot possibly phone home, you want to take this into account.

As far as ads go, IPC is already being used for this, and has been for years. There are many instances of apps fetching apps through Play Services instead of directly fetching them themselves. So blocking the app's access to the internet doesn't block ads, you would have to block Play Services itself, and most people can't block Play Services without breaking a lot of unrelated functionality they rely on.


Also: if you don't currently use split tunneling for anything, you can repurpose it to block specific apps, if you need to. If you enable "Block connections without VPN" in the OS's VPN settings, you can exclude apps from the VPN, and those apps will not have internet access because the OS is blocking everything that isn't going through the VPN.

This will not help if you actually rely on split tunneling and aren't using "Block connections without VPN", but if you don't actually need split tunneling, you can sort of get what you want by doing this instead.

@denosaurtrain
Copy link
Author

Interesting stuff! Lots of that was new info to me. It's good to know there's a workaround (if, like you said, one can live without split tunneling for other purposes).

if your threat model needs you to make sure certain apps cannot possibly phone home

I see your point, but I don't think that negates the benefit for most use cases. Nothing short of root access could achieve full isolation, and even then it's not trivial. As long as an adversary controls any apps that can phone home, preventing that adversary's other apps from phoning home would be nigh impossible. At that point you're talking about needing a virtual machine for each app, which seems like too high a bar for addressing pain points like, "my child's data is being trivially hoovered up by every dumb game installed on her device, and I can't stop it unless I also uninstall her VPN and install a firewall instead."

I figure it's a power law thing: having any blocking ability at all will stop >99% of apps. For people who need to block that last 1% probably need a more sophisticated solution anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Android Issues related to Android feature request For issues asking for new features
Projects
None yet
Development

No branches or pull requests

5 participants