APK Static Analysis, Explained
Published · Strata Security
1What Static Analysis Actually Is
Static analysis examines a compiled APK — the manifest, DEX bytecode, resources, and signing certificate — without ever running the application. No emulator, no device, no network traffic to observe. This is a meaningfully different technique from dynamic analysis, which executes the app (in an emulator, a device, or an instrumented runtime) and observes what it actually does at runtime. Static analysis is faster, requires no test environment, and works on any APK regardless of what device or OS version it targets — but it inherits real limitations from never seeing the app actually run, covered in section 3.
2What Static Analysis Reliably Discovers
Four categories of finding are well-suited to static analysis, because they're properties of the compiled artifact itself rather than its runtime behavior:
- Manifest declarations — every permission the app requests, whether activities/services/receivers/providers are exported (and to whom), debug and backup flags, and target SDK version. All of this is declared in structured XML and parseable with certainty.
- Network configuration — the Network Security Config and the
usesCleartextTrafficmanifest flag both state, unambiguously, whether the app permits unencrypted HTTP traffic and under what conditions. - Embedded strings — DEX bytecode string scanning surfaces hardcoded API keys, tokens, and URLs compiled directly into the app, including ones a developer assumed were only used at build time.
- Signing and certificate properties — signing scheme version, whether the release build was signed with the shared Android debug key, and certificate validity are all readable directly from the APK's signing block.
Concretely, this is what an exported-activity finding looks like at the source — a manifest entry with no permission requirement, reachable by any other app on the device:
<activity
android:name=".AdminPanelActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
</intent-filter>
</activity>
<!-- No android:permission attribute -- any installed app can
launch this activity directly via an implicit intent. -->A tool reporting this finding would typically emit something structured like:
{
"id": "M8-exported-activity-001",
"severity": "high",
"owasp_mobile": "M8",
"cwe": "CWE-926",
"component": "com.example.app.AdminPanelActivity",
"evidence": "android:exported=\"true\" with no android:permission",
"file": "AndroidManifest.xml",
"remediation": "Set android:exported=\"false\", or require a signature-level permission if external access is intended"
}3What Static Analysis Cannot See
Being precise about the limits matters more than the capabilities list, because overclaiming here is exactly how a security tool loses credibility with the engineers who have to act on its output.
- Whether a declared permission is actually exercised. A manifest entry for
READ_CALL_LOGis visible to static analysis; whether the code path that uses it is reachable, dead, or gated behind a feature flag is not — that requires either code review or runtime observation. - Live network behavior. Static analysis can tell you certificate pinning is configured; it cannot confirm the pin is actually validated correctly at runtime, or that a proxy can't still intercept traffic through a bug in how the pin is checked.
- Logic vulnerabilities that depend on runtime state. A race condition, an authorization check that's bypassable only under a specific sequence of API calls, or a bug that only manifests with a particular server response are all outside what a static pass over the binary can find.
- Anything hidden behind heavy obfuscation. ProGuard/R8 obfuscation renames classes and methods but doesn't remove string literals — secret scanning still works — but logic-level obfuscation or packing can hide behavior that only dynamic analysis or manual reverse engineering would recover.
4Why False Positives Happen
Every static analysis tool produces some false positives, and understanding the common causes makes triage faster:
- A permission is declared because a bundled third-party SDK requests it, not because the app's own code uses it — the manifest can't distinguish "my code needs this" from "a library I included needs this."
- A cleartext URL string is found inside a third-party SDK's compiled code, not anything the app's developers wrote or control directly.
- Debug-only or test code paths that never ship in a production build still exist in the binary and get scanned along with everything else.
- Generic secret-pattern matching flags a string that has the shape of a credential (long, high-entropy) but is actually a non-sensitive identifier, like an analytics client ID.
5What Manual Validation Should Still Check
A finding from static analysis is a candidate, not a verdict. Before treating one as confirmed:
- Trace whether the flagged permission or API is actually called from a reachable code path, not just declared.
- Confirm whether a flagged configuration applies to the production build variant, or only to a debug/staging variant that never ships.
- Read the surrounding code or string context around a suspected secret before treating it as a real credential leak.
- Cross-reference a flagged network endpoint against known first-party domains — an unfamiliar domain from a bundled SDK is a different risk profile than one the app's own backend uses.
This is standard reverse-engineering territory, not a Strata-specific workflow: pulling a manifest with apktool, reading decompiled Java with jadx, or inspecting raw DEX bytecode with dexdump are the tools most mobile security engineers reach for to manually confirm exactly this kind of finding — a static scanner's job is to point at the right place to look, not to replace that step.
A concrete triage path for an exported-component finding:
| Question | If yes | If no |
|---|---|---|
| Does the component handle sensitive data or actions? | Continue triage | Likely low severity even if exported |
| Is it exported intentionally (deep link, share target)? | Confirm input validation on the exported entry point | Set android:exported="false" |
| Is a permission declared to protect it? | Confirm the permission's protection level isn't "normal" | Add a signature-level permission or remove the export |
6Common Android Findings, Ranked by How Often They Matter
| Finding | How common | Typically real? |
|---|---|---|
| Cleartext traffic permitted | Very common | Usually a real gap, worth fixing |
| Debug flag in release build | Common | Usually real — often a build config mistake |
| Exported component without permission | Less common | High severity when real; verify reachability first |
| Hardcoded low-risk analytics key | Very common | Often informational — confirm what the key actually grants |
| V1-only APK signing | Uncommon on modern build tooling | Real when found — confirm build pipeline signing config |
| Dangerous permission, no clear use | Common | Often from a bundled SDK — trace before assuming intent |
7Framework Mapping
The same findings map cleanly across OWASP Mobile Top 10, CWE, and — where a finding has a clear adversarial use — MITRE ATT&CK Mobile:
| Finding | OWASP | CWE | ATT&CK Mobile |
|---|---|---|---|
| Exported component, no permission | M8 | CWE-926 | — |
| Cleartext traffic permitted | M5 | CWE-319 | T1437 (App. Layer Protocol) |
| Hardcoded credentials | M1 | CWE-798 | — |
| Debuggable release build | M7 | CWE-489 | T1418 (Software Discovery) |
| V1-only signing (Janus) | M7 | CWE-347 | — |
Not every finding maps to an ATT&CK technique, and that's expected — ATT&CK documents observed adversary behavior, not every possible weakness. A finding earns an ATT&CK reference when it corresponds to a specific, named technique an attacker would actually use; forcing a mapping where none fits just adds noise.
8How This Maps to Strata
Strata performs exactly this kind of static analysis on every APK scan, and reports each finding with the evidence needed for the manual validation described above — file location, matched pattern, and OWASP mapping. See APK Security Scanner for the full technical breakdown, IPA Security Testing, Explained for the iOS equivalent, or the Mobile App Security Checklist for the full manual assessment methodology this fits into.
This article supports APK Security Scanner — see the product page for how Strata applies these ideas directly.
Visit APK Security Scanner →