The following description explains, at the high-level, how the app blocklist is used by DuckDuckGo App Tracking Protection beta on Android.
-
Intercept network requests from all apps by utilizing VPN APIs. We exclude certain apps from interception, such as those that do not work with VPNs or apps that rely on tracking domains to function. Our full list of excluded apps can be found in the
unprotectedApps
object here: https://github.com/duckduckgo/privacy-configuration/tree/main/features/app-tracker-protection.json -
For each intercepted request, take the hostname of the request (including subdomains) by parsing DNS queries, HTTP, or the TLS SNI. Check for a corresponding key in the trackers object. Continue removing subdomains until a match is found or you no longer have a valid hostname.
- If no match is found, don't block the request
- If a match is found, continue to the next step
-
If a match is found: check if the requesting app's package name exists in the packageNames object of the blocklist.
- If the package name exists, compare the owner name of the package to the owner of the tracker.
- If they match, the request is considered first-party, don't block it.
- Otherwise, mark the request as third-party and continue to the next step.
- If the package name does not exist, mark the request as third-party and continue to the next step.
- If the package name exists, compare the owner name of the package to the owner of the tracker.
-
Check if there is an exception for the given app/tracker pair as certain apps rely on specific trackers and stop functioning correctly if the tracker is blocked. Our full list of exceptions can be found in the
appTrackerAllowList
object here: https://github.com/duckduckgo/privacy-configuration/tree/main/features/app-tracker-protection.json- If there are no exceptions, block the request
- If there is a matching exception, don't block the request
See the function shouldAllowDomain
in https://github.com/duckduckgo/Android/tree/develop/app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/integration/NgVpnNetworkStack.kt for an example of how to use both the blocklist and the exclusions.
Consider the following tracker
"example-tracker.com": {
"owner": {
"name": "Example Tracker",
"displayName": "Example Tracker"
},
"default": "block"
}
and the following app/tracker exception:
{
"domain": "example-tracker.com",
"packageNames": [
{
"packageName": "com.game.app"
}
]
}
This tracker above has default: block
.
We will block all third-party requests from this tracker unless there is an exception for this tracker within a specific app.
App | App Developer | Host | Block | Reason |
---|---|---|---|---|
com.weather.app | Unknown | example-tracker.com | true | default set to 'block' |
com.example.app | Example Tracker | example-tracker.com | false | first-party request |
com.game.app | Unknown | example-tracker.com | false | app/tracker exception match |
This tracker has default: ignore
. There are some trackers that cannot be blocked due to breakage.
"image-cdn-example.com": {
"owner": {
"name": "Example LTD.",
"displayName": "Example Site"
},
"default": "ignore"
},
App | App Developer | Host | Block | Reason |
---|---|---|---|---|
com.weather.app | Unknown | example-tracker.com | false | default set to 'ignore' |
com.example.app | Example Tracker | example-tracker.com | false | default set to 'ignore' |
com.game.app | Unknown | example-tracker.com | false | default set to 'ignore' |