Skip to content

APK Scans

Before an APK gets accepted into our repository, it has to pass multiple scans. First, for updates, the signing key must match. But there are several more scans performed on APKs:

Permissions requested by apps

In our repository browser, the permissions an app requests are made transparent on a per-package base (i.e. they are shown for each version of an app separately, as they might change with each release). Permissions recorded with the IzzyOnDroid app lists are linked there for their resp. background. In addition to that, permissions which are considered to be „sensitive“ are highlighted (bold) and, if their need was clarified, accompanied by a short reason for the need.

Sensitive permissions which were not yet clarified receive an additional highlighting (italics and a warning color). Usually we reach out to the corresponding developer(s) and ask for clarification when we see such, but we might not yet have covered all apps. So if you see such, be welcome to help out: check if the app details show an „Issues“ link (leading to the app’s issue tracker), follow it, and search if a corresponding issue already exists. If so, feel welcome to „chime in“ (by adding a thumbs-up to signal you’d like to know that, too, or a comment if useful) – if not, please open one, ask, and if you receive an explanation just leave a comment @mentioning one of us (e.g. Izzy is izzy at Codeberg, and IzzySoft at GitLab & Github) so we can include the proper explanation(s) here.

Apps requesting dangerous permissions which are unclear and are not (or cannot be) clarified by their corresponding developer(s) might lead to their removal from our repo. One special case in this regard is REQUEST_INSTALL_PACKAGES with an app that’s not a package manager (e.g. an F-Droid client, APK Updater, Obtainium are examples of apps needing this), as this often indicates an integrated self-updater which would be a violation of the IzzyOnDroid App Inclusion Policy. Those are tolerated when they are clearly opt-in (i.e. disabled by default) and before you can enable them, make clear where the APKs are downloaded from and what the implications are. If those updates are downloaded from outside of our repository, all the „screening“ described here would be bypassed. We’re not saying you cannot trust the developers, but mistakes can happen to the best, and additional screening helps detecting what might have „accidentally slipped in“. So take extra vigilance with those self-updaters, please. Yes, you might get a new release a few hours earlier, but always ask yourself if it’s worth it.

Manifest checks

Each Android app has an AndroidManifest.xml, where its activities, services, permissions and more are defined. Scans extract this file and run several checks on them:

  • Flags:
    • Apps flagged for debugging are intended for development – not for deployment. Such apps are only accepted in exceptional cases, and would then be marked with the ApplicationDebuggable anti-feature.
    • Apps flagged testOnly are not intended for contribution and thus should not enter our repository (such APKs would be rejected).
    • The usesCleartextTraffic flag should be avoided wherever possible. There are exceptions (e.g. for local resources), but all „public“ traffic (i.e. connections outside the local environment) should be properly encrypted via HTTPS to minimize the risk for MITM etc.
  • Sensitive permissions: Permissions sensitive for your privacy (e.g. access to your contacts, calendar entries, installed apps, media files) are screened. Where justified, they go to a per-app allow-list. The corresponding authors/developers are contacted for clarification/adjustment where needed.
    In our repository browser, app details highlight those: bold for sensitive permissions, bold and colored for sensitive permissions which have not yet been verified/allow-listed, and for each permission on hover a short description with what it stands for. Verified sensitive permissions also show a short text with an explanation on what they are needed for by the specific app.
  • Sensitive service intent filters: some of them indicate possible risks, so these are screened the same way flags and permissions are:
    • AccessibilityService is to assist users with disabilities in using Android devices and apps. To do this, they allow to automatically perform tasks intentionally designed to be done manually by the person operating the device (think e.g. of applying certain settings or confirmations). So usage of this service must be well justified.
    • VpnService, as its name suggests, is intended for VPN clients. Another group having this justified implicitly are non-root firewalls like NetGuard and non-root ad-blockers, which need this to filter traffic.
    • InputMethod is reserved for, well, apps providing input methods. A keyboard app requires this to work. But there are other types of input methods where this is justified, e.g. barcode readers inside an inventory app (filling the field with the product code).

These checks are performed manually on new apps before they are included with the repo, and automatically for each incoming update.

SigningBlock checks

As the name suggests, these blocks are inserted when the APK is being signed. Signing is done either by the developers themselves, or by Google when the app is listed on Google Play and the developer decided to leave signing to the PlayStore. While one would assume only details of the signing itself (information about the certificate and checksums) to be present here, it turns out other things can enter this area as well. But apart from the APK signature scheme blocks (which cover exactly that), there are others which raise at least some warning flags:

  • DEPENDENCY_INFO_BLOCK: This is supposed to contain a binary representation of the app’s build dependencies – but the BLOB is encrypted with a public key belonging to Google. So only Google can see and read what’s in here – and nobody else can even verify nothing else was included. Which not only makes it useless to anybody except Google, but it’s also intransparent and bears possible danger.
  • GOOGLE_PLAY_FROSTING_BLOCK: this BLOB is added by Play Store to prove the particular file was downloaded from Play Store. It includes a rather complex metadata chunk encoded using Protocol Buffers. While protobuf is an open source format, without the definition file it’s hard to decipher – and rather useless for the FOSS world.
  • SOURCE_STAMP_V1_BLOCK, SOURCE_STAMP_V2_BLOCK: Details on this can e.g. be found in SourceStampVerifier.java, where a comment describes them as
    SourceStamp improves traceability of apps with respect to unauthorized distribution. The stamp is part of the APK that is protected by the signing block. The APK contents hash is signed using the stamp key, and is saved as part of the signing block.
    In the open source world and with free/libre FOSS licenses, there should be no such thing as „unauthorized distribution“: the licenses make clear that the Four Essential Freedoms of Free Software are guaranteed – which include „The freedom to redistribute copies so you can help your neighbor“ (freedom-2) and „The freedom to distribute copies of your modified versions to others“ (freedom-3). It seems this is intended to ensure that all split APKs are coming from the same source, and the code to check that is public/FOSS, so we don't see why this should raise concerns – except for it being inserted by a 3rd party which is most likely Google.
  • MEITUAN_APK_CHANNEL_BLOCK: this block includes JSON with some metadata, used by Chinese company Meituan. While „JSON metadata“ at first glance might sound harmless and innocent, it can also be used to inject payload (which Meituan in fact does), so this must be considered a risky one.

There might be other blocks which are not (yet) covered here. As the Meituan example shows, there might be other risky ones using this for payload; should we become aware of any such, they will of course be added to this check.

Library scan

APK files are also checked for libraries they are using. This is done locally, using our own LibraryScanner. For display with our repository browser, findings are grouped into three categories:

  • Libraries: These are usually development tools and libraries for „common tasks“ like parsing structures or dealing with network connections. Maps and social networking also fall into this category.
  • Payment Modules: Basically, „all things money“. This is usually for in-app purchases, but could also be for „money transfers“.
  • Ads & Analytics: Our favorites. Software being free and open source doesn't mean the compiled app cannot have some extras. Usually, if there are ad or analytics modules, that's also pointed out in the „AntiFeatures“ in the app description.

Our library definitions also include markings for anti-features, where that applies. So a suddenly added „offending library“ would automatically trigger a warning, so the corresponding anti-feature will be added – and the corresponding developer informed to hopefully have the offender removed with the next release. Depending on the offenders, this can also lead to the update being rolled back (and updates disabled until the situation is solved), or even the app being removed.

Malware scan

Apps in this repo are scanned for malware, using the services of VirusTotal. VirusTotal currently runs more than 60 engines to check files, which is quite some coverage. However, results differ between engines: some are more prone to „false positives“ than others, and some even report ads as malware (we might tend to agree on that). So results might look different in our repository browser, depending on the findings. We differentiate between „passed cleanly“ (no findings, thus a green shield), a single finding (most likely a false positive), less than 5 findings (warning, but still most likely false positives), 5 or more findings (alert + red shield). The latter you should see almost never; a good example for such a case would be an app testing your device for vulnerabilities: as it imitates malware, scanners are bound to fire. Starting with the „warning“ level, we manually cross-check the findings.

Except for the „pending“ shield, the label will always link to the corresponding detail page at the VirusTotal website. Feel encouraged to check that. If a file is marked by a yellow or red shield, also check the app's description, which might hold further hints. Sometimes a finding might be „normal“ (e.g. a vulnerability test suite could easily trigger a „false alert“, as described above). Moreover, some scanners thread a „PUA“ (potentially unwanted addon/application) as alert – as indicated above.

Further readings

Ramping up security: additional APK checks are in place with the IzzyOnDroid repo