SSL pinning bypass is a required skill for any serious Android security tester. Without it, you cannot intercept app traffic, and without intercepting traffic, you are testing blind. Most production apps implement some form of certificate pinning — and your job is to get past it before the real test begins.
This guide covers every major SSL pinning bypass technique for Android: from Frida scripts and objection to network security config overrides, Magisk modules, and low-level native hooks. Organized by what you have available and what the app is doing to stop you.
What SSL Pinning Actually Does
Standard TLS relies on the system certificate store. If you install a proxy CA certificate (like Burp Suite) as a trusted CA on the device, the app accepts connections proxied through Burp. Certificate pinning breaks this by hardcoding expected certificate values into the app itself — regardless of what the system trusts, the app rejects any certificate that does not match its internal list.
There are two main types you will encounter:
- Certificate pinning — the app checks the exact certificate (leaf or root) against a hardcoded hash or the certificate itself
- Public key pinning — the app checks just the public key portion, so it survives certificate renewal but still blocks your proxy CA
Pinning can be implemented at multiple layers: network security config (declarative), OkHttp (most common Java library), TrustManager (custom), NSURLSession on iOS, or native C/C++ code (hardest to bypass). Each requires a different approach.
Method 1: Network Security Config Override (Easiest)
Android allows apps to declare pinning configuration in res/xml/network_security_config.xml. If the app uses this approach (rather than code-based pinning), you can bypass it by repackaging the APK with pinning disabled.
Step 1 — Decompile the APK:
Step 2 — Check if network_security_config.xml exists and find the pin entries:
cat target_app/res/xml/network_security_config.xml
Step 3 — Remove or modify the pin-set entries. Replace any <pin-set> block with a <trust-anchors> block that trusts user certificates:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config>
Step 4 — Rebuild, sign, and install:
apktool b target_app/ -o target_app_patched.apk
# Sign with apksigner or jarsigner
keytool -genkey -v -keystore test.keystore -alias test -keyalg RSA -keysize 2048 -validity 10000
apksigner sign --ks test.keystore --out target_signed.apk target_app_patched.apk
adb install target_signed.apk
Works when: App uses network_security_config for pinning
Fails when: App does code-based pinning (OkHttp CertificatePinner, custom TrustManager)
Method 2: Objection (Fastest for Most Apps)
Objection wraps Frida with pre-built scripts for common mobile security tasks. Its SSL pinning disable command handles the most common pinning implementations automatically.
This single command hooks: OkHttp3 CertificatePinner, TrustManagerImpl, SSLContext, X509TrustManager, Conscrypt, and several other common implementations. For many apps this works immediately with no customization needed.
Works when: App uses standard Java/Kotlin networking libraries
Fails when: App uses native code for TLS, custom obfuscation, or actively detects Frida
Method 3: Frida Scripts (Targeted Control)
When objection does not work, write a targeted Frida script. The advantage: you can hook the exact method the app uses instead of spray-hooking everything.
OkHttp3 CertificatePinner Hook
Java.perform(function() {
// Hook OkHttp3 CertificatePinner
try {
var CertificatePinner = Java.use("okhttp3.CertificatePinner");
CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function(hostname, certificates) {
console.log("[*] OkHttp3 CertificatePinner.check() bypassed for: " + hostname);
return;
};
CertificatePinner.check.overload('java.lang.String', '[Ljava.security.cert.Certificate;').implementation = function(hostname, certificates) {
console.log("[*] OkHttp3 CertificatePinner.check() bypassed for: " + hostname);
return;
};
console.log("[+] OkHttp3 CertificatePinner hook installed");
} catch(e) {
console.log("[-] OkHttp3 hook failed: " + e);
}
});
TrustManager Hook (Custom Implementations)
Java.perform(function() {
// Override TrustManager to accept all certificates
var TrustManager = Java.registerClass({
name: "com.bypass.CustomTrustManager",
implements: [Java.use("javax.net.ssl.X509TrustManager")],
methods: {
checkClientTrusted: function(chain, authType) {},
checkServerTrusted: function(chain, authType) {},
getAcceptedIssuers: function() { return []; }
}
});
var SSLContext = Java.use("javax.net.ssl.SSLContext");
var TrustManagers = Java.array("javax.net.ssl.TrustManager", [TrustManager.$new()]);
var SSLContextInit = SSLContext.init.overload(
"[Ljavax.net.ssl.KeyManager;",
"[Ljavax.net.ssl.TrustManager;",
"java.security.SecureRandom"
);
SSLContextInit.implementation = function(km, tm, sr) {
SSLContextInit.call(this, km, TrustManagers, sr);
console.log("[*] SSLContext.init() hooked — custom TrustManager injected");
};
});
Universal SSL Kill Switch Script
The ssl-kill-switch scripts (available on GitHub for Android and iOS) hook at a lower level than individual library hooks. They target the Android SSL implementation directly via Conscrypt and are useful when library-level hooks miss something.
# Run frida script against the app
frida -U -f com.target.app -l ssl_bypass.js --no-pause
Method 4: Magisk + TrustUserCerts (Root Required)
On rooted devices with Magisk, the TrustUserCerts module moves your user-installed CA certificates into the system store. Apps that only check the system certificate store (which is most apps that do not implement explicit pinning) will then trust your proxy CA automatically — no Frida required.
- Install Magisk on your device/emulator
- Install the TrustUserCerts Magisk module
- Install Burp Suite CA certificate as a user certificate
- Reboot — the module copies user certs to the system store
Best for: Testing apps that check the system store but do not implement explicit pinning
Note: This alone does not bypass explicit certificate or key pinning implemented in code
Method 5: Native Hook with Frida (Advanced)
Some apps implement TLS validation in native C/C++ code. This is intentional — it is much harder to bypass than Java-layer pinning. You will see this in banking apps, fintech, and security-focused applications.
Identifying native pinning:
# Check what .so files the app ships
unzip -l app.apk | grep "\.so"
# Look for SSL-related functions in native libraries
readelf -s lib/arm64-v8a/libnative.so | grep -i "ssl\|cert\|pin\|trust"
# Or use strings
strings lib/arm64-v8a/libnative.so | grep -i "sha256\|pin\|fingerprint"
For native pinning bypass, you hook the underlying OpenSSL or BoringSSL functions directly:
// Hook SSL_CTX_set_verify in BoringSSL (used by many Android apps)
var SSL_CTX_set_verify = Module.findExportByName("libssl.so", "SSL_CTX_set_verify");
if (SSL_CTX_set_verify) {
Interceptor.replace(SSL_CTX_set_verify, new NativeCallback(function(ctx, mode, callback) {
console.log("[*] SSL_CTX_set_verify hooked — verification disabled");
// Call with SSL_VERIFY_NONE (0)
}, "void", ["pointer", "int", "pointer"]));
}
This requires finding the correct library name and function export. Use frida-ps -U and Ghidra to map the native code before hooking.
Troubleshooting: When Nothing Works
The App Detects Frida
Some apps scan for Frida agent signatures, check for frida-server processes, or detect /proc/maps entries. Signs: app crashes or exits when you attach Frida, or logs show “tamper detected.”
Solutions:
- Use a custom Frida gadget embedded in the APK (instead of frida-server)
- Use frida-server with a renamed binary to avoid process name detection
- Hook the detection function itself and return false
- Patch the app statically (apktool) to remove detection checks
The App Uses Certificate Transparency
Some apps also verify Certificate Transparency logs, rejecting certificates (including intercepting proxy certs) that are not in public CT logs. This is rare in mobile apps but exists. The bypass requires hooking the CT verification layer specifically.
Pinning in a Third-Party SDK
Sometimes the pinning is not in the app code — it is in an embedded analytics, payment, or security SDK. These often have their own TrustManager implementations. Decompile the app, find the SDK package, and look for its pinning logic specifically. Common culprits: Akamai, Appdome, Guardsquare DexGuard.
Pinning Hostname Mismatch
If you bypass pinning but traffic still fails, check: is the app connecting to a different hostname than you expected? Decompile and search for all hardcoded hostnames and the specific endpoints they call. Some apps have a staging vs production endpoint split and only pin the production host.
Setting Up Burp Suite for Android Traffic Interception
Once pinning is bypassed, you still need the proxy configuration correct:
- In Burp: Proxy → Options → Add listener on all interfaces, port 8080
- On the device: WiFi settings → Proxy → Manual → your machine IP, port 8080
- Navigate to http://burp in device browser, download and install the Burp CA
- On Android 7+: add the CA as user cert, then use TrustUserCerts or the nsc_bypass method above
For apps using mutual TLS (client certificates), you also need to extract the client certificate from the app and install it in Burp. These are typically stored in the assets directory or derived from device-specific keys.
Automating SSL Bypass with Djini.ai
Once you have traffic flowing through your proxy, the next step is systematically testing every API endpoint the app uses. Djini.ai can take your Burp export and automatically test for authentication flaws, authorization bypass, injection vulnerabilities, and business logic issues across all captured endpoints.
The SSL bypass is the prerequisite. The automated API analysis is what turns visible traffic into a comprehensive security assessment.
Practice Labs
The best way to learn SSL pinning bypass is to practice on apps designed for it:
- Mobile Hacking Lab — dedicated SSL pinning labs with guided objectives, from basic OkHttp bypass to native library pinning
- DVIA (Damn Vulnerable iOS/Android Application) — multiple pinning implementations to bypass in a single app
- InsecureBankv2 — classic vulnerable Android app with several security controls to bypass including pinning variants
The difference between someone who can bypass SSL pinning and someone who cannot is not intelligence — it is whether they have seen each implementation variant before. Practice on intentionally vulnerable apps until each method is automatic, then these techniques become 5-minute steps in a pentest rather than hours of research.
Want structured mobile security training? Mobile Hacking Lab has dedicated labs for every SSL pinning bypass technique covered here — from basic objection usage to native Frida hooks. Start free at mobilehackinglab.com.



