DEV Community

Tacuns
Tacuns

Posted on

The VPN Permission Is the Feature, Not the Catch

Every no-root Android firewall asks for VPN permission. And a good number of people see that prompt, decide the app is lying about privacy, and uninstall on the spot.

I get the reflex. An app that promises nothing leaves your phone, asking to handle all your traffic, reads like a contradiction. But the contradiction is in the word "VPN", not in the thing the permission actually does. Android overloaded one API, and that overloading costs privacy tooling real users every day.

Android will not tell an app what other apps are doing

Here is the constraint. On a stock, unrooted Android device, there is no API that says "Instagram just opened a socket to this address." Per-UID network accounting gives you byte counters, not destinations. /proc/net/tcp was locked down years ago. Packet capture needs root. Netfilter rules need root.

What you get instead is VpnService. Register as a VPN, and the system hands your app a TUN interface plus every outbound packet, with the originating app resolvable via getConnectionOwnerUid(). That is the whole reason it is used. Not tunneling. Visibility and the ability to drop a packet.

So the permission is not a side effect of building a firewall. It is the firewall. There is no second door.

Local VPN vs remote VPN

Both show the same key icon in your status bar, and that is the root of the confusion. They are not the same shape of software.

A remote VPN opens the TUN interface, encrypts your packets, and ships them to a server somewhere else. That server sees your traffic, terminates it, and forwards it on. Your public IP becomes the server's. You are trusting an operator you cannot inspect.

A local VPN opens the same TUN interface and terminates it in the same process, on your phone. Packets are inspected, allowed or dropped, and the allowed ones go out of your real network interface exactly as they would have. No server. No operator. No IP change. The "tunnel" is about four inches long.

Android has no separate permission for the second case. Same prompt, same icon, wildly different trust model.

Do not take my word for it. Check.

This is the part I actually care about, because "trust me" is not an argument and the people being skeptical are being skeptical correctly.

Three checks, none of them require any technical skill:

  1. Does it ask you to create an account? A remote VPN has to know who you are, because someone is paying for that bandwidth. A local filter has nobody to bill and nothing to associate you with.
  2. Does your public IP change? Load any "what is my IP" page before you enable it and after. If the number is identical, nothing is being routed anywhere. This is the single most convincing test and it takes thirty seconds.
  3. What does the app do when it has no internet? A local filter keeps working. It is making decisions on-device. A remote tunnel just breaks.

Run those on any firewall app, including mine. Especially on mine.

The trade-off is real, and nobody mentions it

Android allows exactly one active VPN at a time. So the moment you run a local filtering app, you cannot also run a commercial VPN. That is a genuine cost, not a footnote, and anyone telling you otherwise is selling something.

It is worth being plain about what each one buys you. A remote VPN hides your traffic from the network you are sitting on. A local filter shows you (and lets you stop) what your own apps are doing. Those are different problems. Most people assume the first one solves the second. It does not: a VPN faithfully carries your tracker beacons to their destination, encrypted end to end.

Where I keep landing

The permission model trained us to evaluate the name of a capability instead of its use. Camera sounds scary, so we think about it. INTERNET is granted at install time, is never surfaced again, and is held by essentially every app on your phone, including the ones that have no business holding it.

So we end up suspicious of the app that asks loudly and incurious about the hundred that never asked at all.

What would actually fix this? A distinct Android permission for on-device filtering, separate from tunneling, with its own prompt text? A system-level indicator that distinguishes a local TUN from a remote one? Or is that just more UI nobody reads?

I lean toward the first, but I would rather hear why that is wrong.

Disclosure and links

I build TACUNS, a free on-device Android firewall: no root, no account, nothing leaves the phone. It does per-app Wi-Fi and mobile blocking, DNS-level ad/tracker/threat blocking, and shows you what your apps are sending out.

Top comments (1)

Collapse
 
gautamtalksdev profile image
Gautam K •

The point that the contradiction lives in the word VPN, not in what VpnService does, is a clear way to put it. With only per UID byte counters otherwise, routing through a local TUN is the only way to see destinations without root. The trust question then shifts to whether anything leaves the device, which a user can't check from the permission prompt. Do you show anything in the app that proves traffic stays local?