BIPI
BIPI

Android App Pentesting: Static, Dynamic, and Pinning Bypass

Cybersecurity

The Android pentest workflow has not changed much: jadx, MobSF, frida, objection. What changes is what you find. Deep links and exported content providers are the modern wins.

By Arjun Raghavan, Security & Systems Lead, BIPI · March 6, 2025 · 8 min read

#android#mobile#pentest

An Android app assessment splits cleanly into static (what the APK contains) and dynamic (what the app does at runtime). The findings that ship to clients are usually a mix: a static review of the manifest reveals an exported component, dynamic instrumentation confirms it is exploitable.

Static analysis methodology

Pull the APK with adb shell pm path com.target then adb pull. Run MobSF for a baseline report. Decompile with jadx-gui to read smali-decompiled Java. Read AndroidManifest.xml first; it tells you everything exposed. Look for android:exported=true on activities, services, receivers, and providers. android:debuggable=true in production is a critical finding.

  • jadx -d out app.apk: full source decompilation. Grep for hardcoded URLs, API keys, and crypto constants.
  • MobSF docker run: scored static report covering manifest, permissions, secrets, and known vulnerable libraries.
  • apktool d app.apk: smali-level inspection when jadx fails.
  • drozer console connect: an old but still useful framework for IPC fuzzing.

Dynamic analysis with frida and objection

On a rooted device or emulator with a Magisk frida-server, attach to the process. objection is the high-level wrapper that does 90 percent of the common tasks: SSL pinning bypass, root detection bypass, keystore dump. Drop to raw frida scripts when objection's bypass fails on a custom pinning implementation.

  • objection --gadget com.target explore: interactive runtime exploration.
  • android sslpinning disable: bypass OkHttp, Conscrypt, and most TrustManager pinning.
  • android root disable: bypass standard root detection.
  • frida -U -f com.target -l custom-pin-bypass.js: load a custom hook for non-standard pinning.

Deep links and content providers, the modern findings

Apps register deep links via intent filters with android:scheme and android:host. If the receiving activity passes URL parameters into a WebView with JavaScript enabled and a JavaScriptInterface, an attacker who controls a link in any other app gets RCE in the target's WebView context. Content providers exported with grantUriPermissions=true frequently leak file paths that traverse outside the intended directory.

Detection

App-side: integrate Play Integrity API for runtime attestation. Detect frida by scanning for known port (27042) and library names. Detect Magisk and rooting via SafetyNet (deprecated) or Play Integrity device verdicts. Server-side: alert on requests with attestation failures, rapid request rates from a single device ID, or impossible client metadata combinations.

Remediation

  1. Set android:exported explicitly on every component. Default to false. For the few that must be exported, enforce signature-level permissions or origin checks.
  2. Implement certificate pinning with a backup pin. OkHttp's CertificatePinner is the standard. Test that the app fails closed when both pins are invalid.
  3. Validate every deep link parameter on the server, not just on the client. Treat deep link inputs as untrusted user input.
  4. Use Play Integrity API for high-value actions (transfers, account changes). Require an integrity verdict server-side; do not trust the client to send it.
  5. Strip android:debuggable, android:allowBackup, and android:cleartextTraffic from production manifests. Enforce via build flavor.
  6. Store secrets in Android Keystore, not SharedPreferences. Use EncryptedSharedPreferences for non-key data.
  7. Run MobSF in CI on every build. Fail the build on critical-rated findings.

Read more field notes, explore our services, or get in touch at info@bipi.in. Privacy Policy · Terms.