While checking one of my own apps with Exodus Privacy, I noticed it had the INTERNET permission even though the code never touches the network. The culprit turned out to be Google ML Kit's barcode scanning library, which a very popular Flutter QR scanner uses under the hood. It adds INTERNET and ACCESS_NETWORK_STATE through a Google transport library, and sends diagnostic data to Google when the scanner is opened (device model, app version, an install-scoped ID, latencies, error codes). Google documents this, but you'd never guess it from an app that just reads a QR code.

A few things I took away from it:

  • A "0 trackers" result on Exodus doesn't mean "no network". Check the permission list too.
  • If an app that should be offline asks for INTERNET, a QR/barcode feature is worth suspecting.
  • For developers: ZXing-based scanners decode entirely on-device and don't pull any of this in. You can confirm with the merged manifest or the manifest-merger report in your build folder.

Has anyone else run into libraries quietly adding network access like this? Curious which others are common offenders.

you are viewing a single comment's thread
view the rest of the comments
[–] [B] 1 point 2 days ago

I shipped an app under a hard rule that android.permission.INTERNET must not appear in the released manifest, so I went looking for this systematically. Answering your actual question, and then the part of this thread I think is wrong.

I checked a handful of library manifests directly rather than going from memory, and got two of my own guesses wrong, which turned out to be the useful result:

  • Firebase declares it per module. firebase-crashlytics, firebase-config, firebase-perf, firebase-firestore, firebase-storage, firebase-database and firebase-functions each declare INTERNET in their own src/main/AndroidManifest.xml. Crashlytics on its own is enough. Most people expect Analytics to be the culprit and add Crashlytics without thinking.
  • Glide does not, and neither does Coil. I was fairly sure they did. In both repos INTERNET appears only in the sample apps and instrumentation tests — Glide expects you to declare it.
  • ExoPlayer / media3 does not either, same pattern: demos and androidTest only.

So the honest answer to "which libraries are the common offenders" is that you cannot predict it, and the two I would have warned people about were clean. That is the argument against the "you should have checked your merged manifest" line in this thread — not that checking is wrong, but that it is a one-time read of a build artifact. Six weeks later someone bumps a version, the permission comes back, and nobody reopens manifest-merger-release-report.txt.

What holds is a check on the shipped artifact, in CI:

aapt2 dump permissions app-release.apk

That reflects what the store is actually serving rather than what your source says. Fail the build if INTERNET appears and the question stops depending on anyone remembering. It has caught a reintroduction for me once already.

One trap if you go that way: tools:node="remove" will strip the permission from the merged manifest, and if the library genuinely needs the network you have turned a build error into a runtime crash on a path you may not test. Dropping the dependency is the real fix, as you did with ZXing.

Your first takeaway deserves underlining. Exodus is signature matching against known trackers, so "0 trackers" means "none it recognises". The permission list is extracted from the binary. Different kind of evidence entirely.

  • source