OnionMasq provides exactly three (3) low-level network security properties.
These properties form the foundation of the high-level properties that we will
communicate to users, via our VPN threat model
(https://gitlab.torproject.org/tpo/applications/vpn/-/issues/1).

[[_TOC_]]

We must test these properties early, as any violations of them by
the Android (and iOS) APIs will inherently result in violations to the
higher-level threat model.

The theory-of-change for this effort is that while we cannot fix platform
issues that we discover here, we **can** affect change in platforms by
publicly pointing out the shortcomings of their APIs, through the combined PR
efforts of the VPN industry.

## Network Bypass Safety

**Definition**: Apps MUST NOT be able to bypass VPN when it is enabled, even
if it is not connected yet, or if the network is temporarily disconnected. The
VPN industry calls this property a "Kill Switch", "Always On VPN Lockdown", or "On Demand".

Always-on VPN in Android was introduced in Android 7 (API 24) and is a feature that guarantees the VPN is started in the boot sequence before any other application gets a chance to create a network connection. Moreover it assures the VPN service is restarted whenever necessary - e.g. on reboot or after the VPN app was killed. Bypassing traffic by apps is still possible depending on the configuration of the VPN, e.g. [if the default routes for IPv4 and IPv6 are not set](https://developer.android.com/reference/android/net/VpnService.Builder#addRoute(java.lang.String,%20int)), if the [bypass flag](https://developer.android.com/reference/android/net/VpnService.Builder#allowBypass()) is set  or if apps are [extempted from the VPN](https://developer.android.com/reference/android/net/VpnService.Builder#addDisallowedApplication(java.lang.String)).

Always On VPN Lockdown was introduced in Android 8 (API 26) as an additional system setting users can manually enable to block traffic if the VPN is not running and for those apps that are extempted from the VPN.

On iOS, network connections that are established before the VPN is run [will leak](https://www.macrumors.com/2022/10/13/ios-16-vpns-leak-data-even-with-lockdown-mode/). Because Apple services will run before the VPN connection can be established, Apple will see your full client IP address history for your hardware-serial-number-linked APN connections, giving them city-level location information via GeoIP. As of this writing, there is no known way with iOS to get around this problem, with the exception of the device always on wifi, with network obfuscation provided upstream.

**Provided By**: On Android, this is in APIv26 (Android 8). (https://developer.android.com/guide/topics/connectivity/vpn#always-on)

### Known Risk Areas

1. Pre-VPN bootup activity
   - During bootup, some devices may not enforce the "Always On"/"On Demand"
     property
2. System Activity
    - "Always On"/"On Demand" may exempt certain system/platform services. iOS/MacOS
      recently placed their system services under control of Network
      Extensions in MacOS 10.15/iOS 12.
      Recently Mullvad reported that Captive Portal connectivity requests to the are *not* routed over the VPN on Android - even in lockdown mode. ([1](https://issuetracker.google.com/issues/249990229), [2](https://issuetracker.google.com/issues/250529027?pli=1)). The same applies to [priviledged apps or tethered traffic](https://issuetracker.google.com/issues/250529027#comment4)
3. Platform API Activity
    - Can calls to various platfom services bypass "Always On"?
4. Exotic networking
    - Multipath TCP: https://blog.disconnect.me/ios-vpn-leak-advisory/

## Network App Isolation

**Definition**: All network activity of each Tor-routed app MUST be isolated
from other apps, on its own circuit. Specific apps MAY bypass Tor entirely, if
the user chooses to allow this.

**Provided By**: XXX: dgoulet/cyberta/eta/ahf: describe how app-id's are passed
in to OnionMasq from Android APIs (also link docs)
Beginning from Android API 29 Android's [ConnectivityManager](https://developer.android.com/reference/android/net/ConnectivityManager#getConnectionOwnerUid(int,%20java.net.InetSocketAddress,%20java.net.InetSocketAddress)) allows to determine a connection's owner UID.
Older Android versions allow applications to read and parse /proc/net/* to determine the UID of a given connection.

### Known Risk Areas

1. Android Intents
   - Android Intents might allow apps to launch each other in ways that
     allow them to make connections on behalf of each other, with identifiers
2. DNS Requests
   - Do DNS requests and system API requests get APP id information in Android
     VPN APIs?
   - Does our DNS cookie workaround help here? ISTR it does...
3. Shared UIDs
   - System apps may get UID 0, and are mixed together
   - Applications signed by the same vendor can overwrite the default behavior and [share an UID](https://developer.android.com/guide/topics/manifest/manifest-element.html#uid) as well. This feature was deprecated in Android API 29.
4. Platform API Activity
   - Can apps call Google Play APIs to cause UID 0 activity?


## Network API Safety

**Definition**: Apps MUST NOT be able to determine the device IP address, MAC
address, IMSI, phone number, or other device identifiers via unpermissioned
platform APIs.

**Provided By**: This property is provided by testing and community feedback.
We ask our community to find 0day here, and we publish it.

### Known Risk Areas

1. WebRTC IP address transmission
   - WebRTC handshakes might enumerate all interface addresses and provide
     them in the ICE handshake
2. STUN IP addresss transmission
   - NAT tunneling APIs may have similar properties
3. Push notifications
   - Push notification registration may allow connect-backs to the device IP
     address, which may reveal it to the app
4. mDNSResponder hacks
   - Registration of the device on the local network may allow weird things
     like determing MAC address, and cloud print service connect-backs.
5. Twitter bag of 0day
   - Twitter is rumored to have a bag of 0day for determining the device phone
     number and other device identifiers. Probably Facebook/WhatsApp and
     TikTok too...
