Android applications handle some of the most sensitive data on any platform — banking credentials, health records, location history, and authentication tokens. Despite this, mobile security is frequently an afterthought compared to web application security, and Android apps routinely contain vulnerabilities that would be caught immediately in a modern web application security program.
This guide covers the best Android security testing tools and frameworks in 2026 — for both static analysis (testing the APK without running it) and dynamic analysis (testing the running app on a device or emulator) — along with the most common vulnerability classes found in Android apps and how to fix them.
Android Security Testing: Static vs. Dynamic Analysis
Android security testing follows the same layered approach used for web application security:
Static Analysis (SAST for Android): Analyzes the APK file, decompiled Java/Kotlin source, or original source code without executing the app. Finds hardcoded secrets, insecure API usage, weak cryptography, exported components, and code-level vulnerabilities.
Dynamic Analysis (DAST for Android): Tests the running application on a real device or emulator. Finds runtime behavior, network traffic vulnerabilities, insecure data storage, and authentication issues that only manifest during execution.
Both are necessary. Static analysis finds code-level problems early; dynamic analysis validates runtime behavior and catches vulnerabilities that only appear during execution.
Top Android Security Testing Tools
1. MobSF — Mobile Security Framework
Type: Static + Dynamic Analysis | Best for: Automated APK analysis, rapid security assessment
MobSF (Mobile Security Framework) is the most widely used open-source Android security testing framework. It performs both static and dynamic analysis of Android APKs (and iOS IPAs) with a web-based UI that makes results accessible to both security engineers and developers.
Static analysis capabilities:
- Decompiles APK using JADX and Apktool
- Extracts and analyzes AndroidManifest.xml for dangerous permissions and exported components
- Detects hardcoded secrets, API keys, and credentials in decompiled source
- Checks for weak cryptographic implementations
- Identifies insecure data storage (world-readable files, unencrypted SharedPreferences)
- Scans for known vulnerable libraries and patterns
Dynamic analysis capabilities:
- Hooks into a running emulator or real device
- Captures network traffic (HTTP/HTTPS) for analysis
- Logs file system activity, database writes, and SharedPreferences changes
- Detects runtime security issues including certificate pinning bypass
Setup:
# Docker — fastest way to get MobSF running
docker pull opensecurity/mobile-security-framework-mobsf:latest
docker run -it --rm \
-p 8000:8000 \
opensecurity/mobile-security-framework-mobsf:latest
# Access at http://localhost:8000
# Default credentials: mobsf / mobsf
Upload an APK and get results: Drop your APK (or IPA) into the web interface. MobSF produces a scored report within minutes, covering Android permissions, security findings, hardcoded secrets, and network security configuration issues.
2. JADX — Java Decompiler for Android
Type: Decompiler | Best for: Manual code review of decompiled APKs
JADX decompiles Android DEX bytecode back to readable Java (and sometimes Kotlin) source code. It is the standard tool for manual static analysis of Android apps when source code is not available.
Key features:
- Converts DEX bytecode to readable Java
- Supports APK, DEX, AAR, and class file input
- GUI and command-line interfaces
- Resource decompilation (XML layouts, strings, drawables)
- Search across decompiled code
# Install JADX
brew install jadx # macOS
# or download from https://github.com/skylot/jadx/releases
# Decompile APK
jadx -d output_directory/ target.apk
# GUI mode
jadx-gui target.apk
What to look for during JADX analysis:
- Hardcoded API keys, tokens, and credentials in string constants
- Cryptographic operations using weak algorithms (
MD5,DES,ECBmode) - HTTP (non-HTTPS) URLs for API endpoints
- Sensitive data written to external storage (
Environment.getExternalStorageDirectory()) - Exported activities and broadcast receivers without permission requirements
- Debug code left enabled (
Log.d()with sensitive data,BuildConfig.DEBUGchecks removed)
3. Frida — Dynamic Instrumentation Framework
Type: Dynamic Analysis / Hooking | Best for: Runtime analysis, bypassing certificate pinning, tracing function calls
Frida is a dynamic instrumentation toolkit that injects JavaScript into native apps at runtime. For Android security testing, it is the standard tool for:
- Bypassing certificate pinning — intercepting HTTPS traffic in apps that implement custom certificate validation
- Tracing API calls — monitoring calls to cryptographic functions, file operations, and network requests
- Bypassing root detection — testing apps that block execution on rooted devices
- Runtime value inspection — reading decrypted values that only exist in memory
# Install Frida tools
pip install frida-tools
# On the Android device (rooted) — download frida-server matching device arch
adb push frida-server /data/local/tmp/
adb shell chmod 755 /data/local/tmp/frida-server
adb shell /data/local/tmp/frida-server &
# On the host — list running processes
frida-ps -U
# Attach to an app and run a script
frida -U -f com.example.app -l my-script.js
Certificate pinning bypass script (Frida):
// bypass-ssl-pinning.js — works for many common implementations
Java.perform(function() {
// Bypass OkHttp certificate pinning
var OkHttpClient = Java.use("okhttp3.OkHttpClient");
OkHttpClient.newBuilder.implementation = function() {
var builder = this.newBuilder();
builder.hostnameVerifier(Java.use("com.android.org.conscrypt.OkHostnameVerifier").INSTANCE);
return builder;
};
// Bypass TrustManager certificate validation
var TrustManager = Java.use("javax.net.ssl.X509TrustManager");
var SSLContext = Java.use("javax.net.ssl.SSLContext");
var TrustManagerImpl = Java.registerClass({
name: "com.custom.TrustManager",
implements: [TrustManager],
methods: {
checkClientTrusted: function(chain, authType) {},
checkServerTrusted: function(chain, authType) {},
getAcceptedIssuers: function() { return []; }
}
});
var context = SSLContext.getInstance("TLS");
context.init(null, [TrustManagerImpl.$new()], null);
SSLContext.setDefault(context);
});
4. Drozer — Android Attack Framework
Type: Dynamic Analysis | Best for: Component security testing (activities, services, providers)
Drozer tests Android’s inter-component communication (ICC) security — the attack surface exposed by Activities, Services, Broadcast Receivers, and Content Providers that are exported to other apps.
# Install Drozer
pip install drozer
# Install the Drozer agent APK on the device
adb install drozer-agent.apk
# Start a session
adb forward tcp:31415 tcp:31415
drozer console connect
Common Drozer commands:
# Find exported components in a package
dz> run app.package.attacksurface com.example.app
# List exported activities
dz> run app.activity.info -a com.example.app
# Start an unexported (but accessible) activity directly
dz> run app.activity.start --component com.example.app com.example.app.AdminActivity
# Query a Content Provider (check for SQL injection)
dz> run app.provider.query content://com.example.app.provider/users
# SQLi test on Content Provider
dz> run app.provider.query content://com.example.app.provider/users \
--projection "* FROM sqlite_master--"
What Drozer finds:
- Exported activities that bypass authentication (directly launchable by any app)
- Content Providers with SQL injection vulnerabilities
- Broadcast Receivers that accept malicious intents
- Path traversal in Content Provider file operations
5. Apktool — APK Decompilation and Repackaging
Type: Static Analysis / Reverse Engineering | Best for: Smali analysis, resource extraction, APK modification
Apktool disassembles APKs to Smali (Android bytecode assembler language) and resources. It is used when you need access to the raw bytecode rather than decompiled Java, or when you need to repackage a modified APK for testing.
# Decompile
apktool d target.apk -o output/
# Examine AndroidManifest.xml
cat output/AndroidManifest.xml
# Rebuild (for patching/testing)
apktool b output/ -o patched.apk
AndroidManifest.xml security review checklist:
<!-- HIGH RISK: Exported component without permission -->
<activity
android:name=".AdminActivity"
android:exported="true" /> <!-- Any app can launch this! -->
<!-- SECURE: Exported with custom permission -->
<activity
android:name=".AdminActivity"
android:exported="true"
android:permission="com.example.ADMIN_PERMISSION" />
<!-- HIGH RISK: Backup enabled (default) — allows adb backup -->
<application android:allowBackup="true" ...>
<!-- SECURE: Disable backup -->
<application android:allowBackup="false" ...>
<!-- HIGH RISK: Debug enabled in production -->
<application android:debuggable="true" ...>
6. Burp Suite — HTTP Traffic Interception
Type: Dynamic Analysis / Proxy | Best for: API traffic analysis, authentication testing
Burp Suite is the standard tool for intercepting and modifying HTTP/HTTPS traffic from Android apps. Configuring an Android device to route traffic through Burp Suite lets you:
- Inspect all API calls made by the app
- Modify requests to test for injection vulnerabilities
- Test authentication and authorization logic
- Identify sensitive data sent without encryption or over HTTP
Android Burp setup:
# 1. Configure proxy on Android device (Settings > WiFi > Proxy)
# Host: your computer's IP
# Port: 8080 (Burp Suite default)
# 2. Export Burp's CA certificate
# Burp > Proxy > Options > Import/Export CA Certificate
# Export as DER, transfer to device
# 3. Install certificate on Android (API 24 and below — auto-trusted)
# Android 7+ requires network_security_config.xml for user certs:
<!-- res/xml/network_security_config.xml — for testing only -->
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<debug-overrides>
<trust-anchors>
<certificates src="user" /> <!-- Trust user-installed certs in debug builds -->
</trust-anchors>
</debug-overrides>
</network-security-config>
<!-- AndroidManifest.xml -->
<application
android:networkSecurityConfig="@xml/network_security_config"
...>
7. SAST for Android Source Code — Offensive360
Type: Static Application Security Testing | Best for: Source code analysis of Android Java/Kotlin projects
When you have access to the Android app’s source code (as part of a security review or development process), a dedicated SAST tool provides significantly deeper analysis than APK-based decompilation.
Offensive360 SAST supports Android Java and Kotlin source code with full taint analysis — tracing user-controlled input from Android entry points (Intents, Content Providers, WebViews) through the application to vulnerable sinks.
Android-specific vulnerability detection:
- Intent injection — malicious extras from Intents used in unsafe ways
- WebView JavaScript bridge attacks —
addJavascriptInterface()exposing Java objects to web content - SQL injection in Content Providers — raw query strings built from Content URI parameters
- Insecure data storage — sensitive data written to
SharedPreferencesin cleartext, or to world-accessible external storage - Hardcoded API keys and secrets — credentials in string resources, BuildConfig fields, or inline constants
- Weak cryptography — use of
MD5,DES, ECB mode,Math.random()for security purposes - Exported component vulnerabilities — activities and services exported without proper permission checks
Most Common Android Security Vulnerabilities
1. Hardcoded API Keys and Secrets (CWE-798)
The most common finding in Android APKs:
// VULNERABLE — API key in source code
public class ApiClient {
private static final String API_KEY = "sk-live-abc123def456xyz789";
private static final String BASE_URL = "https://api.example.com";
}
Keys hardcoded in source are trivially extracted from any APK using JADX or strings analysis. Even obfuscated apps can have keys recovered through dynamic analysis.
Fix: Use Android Keystore for storing sensitive keys, and fetch API credentials from a secure backend at runtime rather than embedding them in the APK.
// BETTER — fetch API token from authenticated backend, store in Keystore
// Never embed long-lived production credentials in the APK
2. Insecure Data Storage
// VULNERABLE — sensitive data in world-readable SharedPreferences
SharedPreferences prefs = getSharedPreferences("user_data", MODE_WORLD_READABLE);
prefs.edit().putString("auth_token", userToken).apply();
// ALSO VULNERABLE — sensitive data on external storage
File file = new File(Environment.getExternalStorageDirectory(), "user_data.json");
// SECURE — private SharedPreferences (default mode)
SharedPreferences prefs = getSharedPreferences("user_data", MODE_PRIVATE);
// SECURE — use EncryptedSharedPreferences for sensitive values
MasterKey masterKey = new MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build();
SharedPreferences encryptedPrefs = EncryptedSharedPreferences.create(
context,
"secure_prefs",
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
3. Exported Components Without Permission Checks
<!-- VULNERABLE — AdminActivity accessible to any app on the device -->
<activity
android:name=".AdminActivity"
android:exported="true" />
// VULNERABLE — no permission check inside the Activity
public class AdminActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// No authentication check — any app can launch this
setContentView(R.layout.activity_admin);
}
}
<!-- SECURE — require custom permission -->
<activity
android:name=".AdminActivity"
android:exported="true"
android:permission="com.example.permission.ADMIN" />
4. WebView Security Issues
// VULNERABLE — multiple WebView security issues
WebView webView = (WebView) findViewById(R.id.webview);
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true); // Often necessary but must be combined with safe URL loading
// HIGH RISK — exposes Java object to all web content
webView.addJavascriptInterface(new MyJavaBridge(), "Android");
// HIGH RISK — loads arbitrary URLs including attacker-controlled pages
String url = getIntent().getStringExtra("url");
webView.loadUrl(url); // Open redirect — attacker can load malicious page with Java bridge access
// SECURE — validate URLs before loading
String url = getIntent().getStringExtra("url");
if (url != null && url.startsWith("https://trusted-domain.com/")) {
webView.loadUrl(url);
} else {
// Reject unknown URLs
finish();
}
// SECURE — restrict JavaScript interface to specific origins
// Use shouldOverrideUrlLoading to enforce allowlists
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
Uri uri = request.getUrl();
// Only allow navigation within your own domain
return !uri.getHost().equals("trusted-domain.com");
}
});
5. Insecure Network Configuration
<!-- VULNERABLE — allows cleartext HTTP traffic (not default in API 28+) -->
<!-- res/xml/network_security_config.xml -->
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" /> <!-- Trusts user-installed certs in production! -->
</trust-anchors>
</base-config>
</network-security-config>
<!-- SECURE — restrict to HTTPS, use certificate pinning for sensitive endpoints -->
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
<domain-config>
<domain includeSubdomains="true">api.example.com</domain>
<pin-set expiration="2027-01-01">
<pin digest="SHA-256">your-certificate-pin-base64==</pin>
<pin digest="SHA-256">backup-pin-base64==</pin> <!-- Always include a backup -->
</pin-set>
</domain-config>
</network-security-config>
Android Security Testing Checklist
Use this checklist for a complete Android application security assessment:
Static Analysis:
- AndroidManifest.xml reviewed for exported components, dangerous permissions, debug flags
- Source code (or decompiled APK) scanned with SAST for injection, hardcoded secrets, weak crypto
- All third-party libraries (AAR/Maven dependencies) checked for known CVEs
- Network security configuration reviewed — no cleartext traffic, no user certificate trust in production
-
allowBackupset to false - ProGuard/R8 obfuscation enabled for production builds
- No sensitive data in
BuildConfig,strings.xml, or raw string constants
Dynamic Analysis:
- All network traffic intercepted and reviewed for sensitive data in transit
- Certificate pinning tested — is traffic interception possible without bypass?
- Exported activities tested for authentication bypass (Drozer / ADB)
- Content Providers tested for SQL injection and path traversal (Drozer)
- SharedPreferences, databases, and files inspected on device for sensitive data storage
- Application behavior on rooted devices reviewed (root detection effectiveness)
- Clipboard sensitive data — does the app prevent auto-fill/clipboard access for password fields?
API and Backend:
- All API endpoints tested for authentication and authorization flaws
- API responses checked for excessive data exposure
- JWT tokens validated for algorithm, expiry, and scope issues
- API keys in app verified as minimum-permission (read-only where possible)
Recommended Android Security Testing Workflow
A practical workflow for Android security assessment:
- Collect and decompile — Download the APK (from Play Store or build pipeline), decompile with JADX and Apktool
- Automated static analysis — Run MobSF for an automated baseline report; review AndroidManifest.xml findings first
- Manual source review — Use JADX to review decompiled code for hardcoded credentials, crypto issues, and WebView configurations
- Source-level SAST (if source available) — Run Offensive360 SAST on the Android Java/Kotlin source for deep taint analysis
- Dynamic setup — Configure Burp Suite proxy on a rooted emulator (Android API 28 emulator recommended)
- Traffic analysis — Intercept and test all API calls for injection, authentication, and authorization issues
- Component testing — Use Drozer to test exported components for access control bypasses
- Runtime hooking — Use Frida to bypass certificate pinning, trace crypto functions, and inspect in-memory values
- Storage review — Pull the app’s private data directory from the device and review for unencrypted sensitive data
OWASP Mobile Top 10 Reference
Android security testing should cover the OWASP Mobile Top 10:
| # | Risk | Primary Test Method |
|---|---|---|
| M1 | Improper Credential Usage | Static (JADX, MobSF) + Dynamic (Burp) |
| M2 | Inadequate Supply Chain Security | SCA (dependency scanning) |
| M3 | Insecure Authentication/Authorization | Dynamic (Burp, Drozer) |
| M4 | Insufficient Input/Output Validation | Static (SAST) + Dynamic (Burp) |
| M5 | Insecure Communication | Dynamic (Burp, Frida) |
| M6 | Inadequate Privacy Controls | Static + Dynamic |
| M7 | Insufficient Binary Protections | Static (MobSF, JADX) |
| M8 | Security Misconfiguration | Static (AndroidManifest.xml review) |
| M9 | Insecure Data Storage | Dynamic (device file inspection) |
| M10 | Insufficient Cryptography | Static (JADX, SAST) |
Offensive360 SAST supports Android Java and Kotlin source code with the same deep taint analysis used for web application security — tracking data from Android Intent extras, Content Provider queries, and WebView input through your application to vulnerable sinks. Run a one-time scan of your Android source code for $500 or book a demo to see the full platform.