Decompile the APK, run it through a static scanner, grep the smali for hardcoded keys, flag the manifest permissions — that workflow finds real issues, and it takes about twenty minutes. It’s also where most “Android pentests” stop. It’s the floor of a mobile assessment, not the ceiling, and the gap between the two is where the impactful findings live.

The component surface a static scan can’t reason about

Every exported="true" activity, service, broadcast receiver, and content provider is attack surface reachable by any other app on the device — no root required, no backend involved. A static tool can tell you a component is exported. It can’t tell you whether the code behind it is safe, because that requires actually exercising it: sending it crafted Intents and watching what happens.

The same handful of patterns show up again and again once you start driving components by hand instead of just reading the manifest:

  • An exported activity or a WebView’s JavaScript bridge trusts a caller-supplied URL or file path without validating where it actually came from — deep link and Intent redirection issues that let one malicious app launch or manipulate a component in another.
  • Zip/path handling during file extraction (backups, downloaded assets, shared files) doesn’t validate entry names, opening the door to writing files outside the intended directory.
  • A PendingIntent is handed to another component without the flags that stop it from being redirected or filled in by whoever receives it.
  • Permissions requested for a feature that was later removed are still enforced nowhere, leaving orphaned access nobody’s watching.

None of that is a lint warning. Each one requires actually driving the app — sending it Intents, poking the exported surface with adb, watching what a component does with data it was never supposed to trust.

The backend is still the backend

The APK is a client. Every API it talks to is fair game, and it’s usually more exposed there than the mobile UI lets on — client-side validation the app enforces is rarely mirrored server-side. Proxy the device through Burp, bypass certificate pinning with Frida, and the app’s real request surface shows up: parameters the UI never lets you touch directly, endpoints the app calls that a browser never would. Once that surface is visible, it gets tested exactly like a web API — the same broken access control patterns we wrote about last time don’t disappear just because the client happens to be an app instead of a browser.

A static report tells you what’s possible. Driving the app and its backend by hand is the only way to tell you what’s actually exploitable.

heckcure