Skip to content

mark apps/builds with ga_trackingId set with Tracking Anti-Feature

Google Firebase Analytics is configured using an XML file, and it seems to require that an value with the key ga_trackingId is included: https://developers.google.com/android/reference/com/google/android/gms/analytics/Tracker

That means that any app that is setting ga_trackingId is most likely configuring Google Firebase Analytics. If not, then that file/key should be removed entirely. It can easily be moved to a flavor also.

@BramBonne @premnirmal @manuelsc @vuze @Nonononoki @tasks @tslocum @secure-system @ellaism @rubenroy @jcarolus if your app is not tracking, please remove ga_trackingId, which is usually set in res/xml/global_tracker.xml or something like that.

@Bubu @Rudloff @uniqx @Bubu @IzzySoft @licaon-kter @relan @mimi89999 any objections?

This was detected by running this script across the whole f-droid.org collection of APKs: https://gitlab.com/trackingthetrackers/scripts/-/blob/master/find-ga_trackingId.py

import os
import sys
import zipfile
from androguard.core.bytecodes.axml import AXMLPrinter
try:
    import defusedxml.ElementTree as XMLElementTree
except ImportError:
    import xml.etree.ElementTree as XMLElementTree  # nosec this is a fallback only

if len(sys.argv) > 1:
    search_dirs = sys.argv[1:]
else:
    search_dirs = ['.']
print('search_dirs', search_dirs)

for d in search_dirs:
    for root, dirs, files in os.walk(d):
        for f in files:
            path = os.path.join(root, f)
            try:
                with zipfile.ZipFile(path) as apk:
                    for info in apk.infolist():
                        if info.file_size < 10:
                            continue
                        name = info.filename
                        if name.startswith('res/') and name.endswith('.xml'):
                            with apk.open(name) as binary_xml:
                                axml = AXMLPrinter(binary_xml.read())
                                resources = XMLElementTree.fromstring(axml.get_xml())
                                for item in resources:
                                    if 'ga_trackingId' == (item.get('name')):
                                        print(path, name, item.get('name'))
            except (zipfile.BadZipFile, AssertionError, TypeError, ValueError) as e:
                #print(path, e)
                pass

Then applied using this script:

import os
import yaml
from fdroidserver import metadata

apps = dict()
with open('ga_trackingId-finds.txt') as fp:
    for line in fp:
        apk, xml, _ = line.split()
        apk = apk.split('/')[1]
        appid = apk[:apk.rindex('_')]
        versionCode = int(apk[:-4][apk.rindex('_') + 1:])
        if appid not in apps:
            apps[appid] = []
        apps[appid].append(versionCode)

for appid, versionCodes in apps.items():
    metadatapath = 'metadata/%s.yml' % appid
    with open(metadatapath) as fp:
        app = yaml.load(fp)
    print(appid, app.get('Repo', '///').split('/')[3], sep='\t')
    for build in app['Builds']:
        if build.get('gradle') is True or build.get('gradle') == 'true':
            build['gradle'] = ['yes']
        if build['versionCode'] in versionCodes:
            build['antifeatures'] = ['Tracking']
    metadata.write_metadata(metadatapath, metadata.App(app))
    os.system("sed -i 's,^      - true,      - yes,' " + metadatapath)
Edited by Hans-Christoph Steiner

Merge request reports