Android leaks your real IP past the VPN, and Google will not fix it
Android has a switch called "Block connections without VPN". Turn it on together with Always-on VPN and the operating system promises that nothing leaves the device outside the tunnel. Two separate research findings this year show that any ordinary app can walk straight past that switch and hand your real IP address to a server of its choosing. Google closed both reports without fixing them.
In short
- Two independent bypasses, found by two different researchers, defeat Always-on VPN with lockdown enabled.
- Neither needs a permission the user has to approve. Internet access is enough, and it is granted automatically.
- The trick in both cases is the same: get a system process to send the packet for you. System processes are exempt from the lockdown rules.
- Google marked one "Won't Fix (Infeasible)" and closed the other without action. GrapheneOS patched the first and says it will patch the second.
What the switch is supposed to guarantee
When a VPN comes up on Android, the system rewrites its routing rules so that apps covered by the VPN can only reach the network through it. Every socket carries a mark telling the kernel which network it belongs to, and if an app tries to bind a socket to the physical Wi-Fi interface directly, the check fails and the call returns a permission error. That is the mechanism behind the setting, and it works.
It works for apps. Sockets owned by system components sit below a threshold called FIRST_APPLICATION_UID and are tagged as system, which lets them reach any network regardless of what a user-space VPN is doing. The system has to be able to talk to the network no matter what, so on its own that exemption is reasonable. It becomes a problem the moment an ordinary app can persuade a system process to send a packet on its behalf.
Leak one: the polite goodbye
Android 16 added a feature for shutting QUIC connections down gracefully. If an app's socket dies unexpectedly, the server on the other end is left with a half-open connection until it times out, so the system now lets an app pre-register a farewell packet that the OS will deliver on its behalf. The researcher who found the flaw, who publishes as lowlevel, named the result the Tiny UDP Cannon.
- The app calls a method on the connectivity service and hands it a UDP socket plus an arbitrary block of bytes. There is no permission check on that call, in the method, in the interface definition or in the security policy.
- The system records the calling app, the network, and the source and destination addresses of the socket.
- The app exits. The kernel reports the socket as destroyed.
- The system process opens a fresh socket on the physical Wi-Fi network, connects it to the recorded destination and sends the recorded bytes. The VPN never sees the packet, and the destination sees the device's real address.
The researcher reported it through Android's vulnerability reward programme. It was closed as Won't Fix (Infeasible), on the reasoning that it is not in the threat model. Mullvad, which does not usually write about other people's bugs, published a warning in May and reported the issue again through the public tracker; the report was then marked inaccessible without explanation. GrapheneOS shipped a fix that turns the optimisation off.
adb shell device_config put tethering close_quic_connection -1 disables the graceful shutdown feature and closes the hole. It survives a reboot but can be undone by a system update, so it has to be reapplied. The cost is that QUIC sockets on the far end stay half-open until they time out.
Leak two: the keepalive the Wi-Fi chip sends for you
The second finding, published on 29 July by Armin Šupuk and written up by Mullvad on 10 September, uses a different door into the same room. Android exposes a public interface for keeping a NAT mapping alive: an app asks the system to maintain a small periodic UDP packet so that a connection through a home router does not get dropped. For efficiency the job is handed down to the Wi-Fi or cellular chip, which emits the packets itself.
The framework accepts that request without checking that the caller actually owns the resource it points at, and without asking whether the caller is subject to VPN lockdown. The keepalive is then produced by the network hardware, below the layer where the VPN rules live. Fixed-format packets on UDP port 4500 arrive at whatever address the app chose, carrying the real IP.
The paper traces the flaw to a trust model that came apart over time. The call started life as a privileged interface taking a raw file descriptor, grew a public entry point, gained resource validation, and then lost it again in a revert. What is left admits the request without proving the caller owns anything.
The reporter's own note on the GrapheneOS tracker is narrower than the paper's headline: on Pixel devices it works over Wi-Fi and mostly not over IPv6. It is also stubborn. The leak keeps running through backgrounding, the lock screen, Doze, battery saver and the process freezer, and it survives the app being force-stopped.
What actually escapes
Not your messages. Both leaks are narrow channels: the app controls where the packet goes and, in the QUIC case, what a few bytes of it contain. What the far end learns is that a specific device with a specific public IP address exists and is online right now. For an app that already knows who you are, that is the missing link between an account and a location, and it defeats the exact thing a VPN was installed to provide.
Why it keeps happening
Both leaks come from the same design decision: convenience features that let a system process act on an app's behalf, written without asking whether the app is allowed to reach the network directly at that moment. The lockdown check filters app identities, so anything performed under a system identity is outside its reach.
This is also not a list of two. In the GrapheneOS discussion a maintainer noted there are at least ten further leaks the project has found and fixed itself, and that leaks which occur without an app deliberately trying to escape are being prioritised over these two. The same maintainer was blunt about the incentives: Google does not pay for VPN leaks, and reports are worth filing for the record rather than in the expectation of a patch.
What you can do
Worth doing
- Treat app installs as the real control. Both attacks require a hostile app already on the device, and neither asks you for anything.
- If you rely on the tunnel for safety rather than convenience, use an Android build that patches these directly, such as GrapheneOS.
- Apply the ADB command above if you are comfortable with it, and repeat it after system updates.
- Remember the second leak favours Wi-Fi on the tested hardware. On mobile data the picture reported so far is patchier.
Does not help
- Switching VPN provider. Every VPN app on Android is affected equally, because the escape happens below them.
- Turning "Block connections without VPN" on. That is precisely the setting being bypassed.
- Waiting for a Google patch. Both reports are closed.
- A kill switch inside the VPN app. It cannot see or stop packets emitted by the system or by the Wi-Fi chip.
What this means for choosing a VPN
It is worth being precise about where the fault lies, because the marketing around this will not be. No VPN service can fix either leak, and none of them caused it: the packets never reach the application layer where a VPN client operates. What a provider can reasonably be judged on here is whether it told its users about the problem at all. If you are picking an app for a phone, our guide to VPNs for Android covers what the app itself controls, which is everything above this layer.
Does this affect iPhones?
Which Android versions?
Can I tell whether an app is doing this to me?
Is my VPN provider at fault?
Should I stop using a VPN on Android?
• Another way to leak traffic on Android has been discovered - Mullvad
• Android NAT-T Keepalive Offload Bypasses VPN Lockdown - Armin Šupuk
• The Tiny UDP Cannon: An Android VPN Bypass - lowlevel
• Any app on recent Android versions can leak certain traffic - Mullvad
• Android NAT-T Keepalive Offload Bypasses VPN Lockdown - GrapheneOS issue tracker