Certificate Pinning Bypass: iOS and Android Traffic Interception
SSL/TLS certificate pinning is the number one obstacle mobile app testers encounter when trying to intercept HTTPS traffic. Without bypassing it, your Burp Suite proxy sees nothing but TLS handshake failures. This guide covers every effective technique for both iOS and Android.
What Is Certificate Pinning and Why Apps Use It
| Bypass Technique | Platform | Tool | Complexity | Notes |
|---|---|---|---|---|
| objection ssl pinning disable | iOS + Android | objection | Easy | Works on most apps, needs Frida |
| Frida hook (manual script) | iOS + Android | Frida | Medium | Custom hook for specific pinning method |
| apk-mitm patching | Android | apk-mitm | Easy | Repackages APK with pinning removed |
| Dynamic patching with EdXposed | Android | EdXposed + JustTrustMe | Easy | Root + Xposed required |
| Network security config override | Android | Manual APK modification | Medium | Edit network_security_config.xml |
| Charles root cert install | iOS | Charles Proxy + Apple Configurator | Easy | Only bypasses basic pinning |
| Reverse engineering + patching | Both | IDA Pro / jadx / Hopper | Hard | Works on any pinning implementation |
Certificate Pinning Bypass Legal Warning
Only bypass certificate pinning on apps you own or have explicit written authorization to test. Bypassing pinning on production apps without authorization may violate terms of service, the CFAA, and similar laws. Always test on dedicated test environments or with proper written scope.
Normally, a TLS client (your app) trusts any certificate signed by a root CA in the system trust store. Certificate pinning adds an additional check — the app also validates that the server's certificate (or its public key) matches a hardcoded value. If it doesn't match, the connection is rejected.
Apps implement pinning to prevent:
- Man-in-the-middle attacks on corporate or public Wi-Fi networks
- Traffic analysis by security researchers and competitors
- Dynamic analysis via proxy tools like Burp Suite and Charles
- Automated API abuse (scraping, bot attacks)
From a pentester's perspective, pinning is a speed bump — not a wall. Every bypass listed here is routinely used in professional mobile assessments.
Burp Suite Proxy Setup for Mobile
Before bypassing pinning, configure your proxy correctly:
# 1. In Burp Suite: Proxy > Options > Add listener
# Bind to: all interfaces, port 8080
# 2. On mobile device: Settings > Wi-Fi > Proxy
# Manual, host: <your machine IP>, port: 8080
# 3. Download Burp CA cert
# Android: http://burpsuite (downloads cacert.der)
# iOS: http://burpsuite (downloads cacert.cer)
# 4. Install cert as trusted CA
# Android: Settings > Security > Install from storage
# iOS: Settings > General > VPN & Device Management > trust the profile
Android: Network Security Configuration
The easiest Android bypass requires patching network_security_config.xml. If it doesn't exist, create it. This approach works without root:
# Step 1: Decompile APK
apktool d target.apk -o target_decompiled
# Step 2: Create or modify res/xml/network_security_config.xml
cat <<EOF > target_decompiled/res/xml/network_security_config.xml
<?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>
EOF
# Step 3: Make sure AndroidManifest.xml references it
# In <application> tag: android:networkSecurityConfig="@xml/network_security_config"
# Step 4: Rebuild and sign
apktool b target_decompiled -o target_patched.apk
keytool -genkey -v -keystore test.keystore -alias test -keyalg RSA -keysize 2048 -validity 365
jarsigner -verbose -sigalg SHA256withRSA -digestalg SHA-256 -keystore test.keystore target_patched.apk test
zipalign -v 4 target_patched.apk target_final.apk
# Step 5: Install
adb install target_final.apk
Android: Frida Universal SSL Kill Switch
For apps with custom pinning logic (OkHttp, native code, custom TrustManager), use the Frida Universal SSL Kill Switch script on a rooted device:
# Clone the script
git clone https://github.com/httptoolkit/frida-android-unpinning
# Run against target app
frida -U -f com.example.targetapp -l ./frida-android-unpinning/frida-script.js --no-pause
This script patches over 15 common pinning implementations including OkHttp3, Appcelerator Titanium, Conscrypt, and Android's built-in NetworkSecurityConfig enforcement.
Android: Objection One-Liner
# Spawn app with pinning disabled
objection -g com.example.targetapp explore --startup-command "android sslpinning disable"
# Or attach to running app
objection -g com.example.targetapp explore
# Then in objection shell:
android sslpinning disable
Android: Xposed TrustMeAlready
If you have Xposed Framework installed, TrustMeAlready disables certificate validation system-wide without per-app scripts:
# Install TrustMeAlready module via Xposed/EdXposed repository
# Enable the module and reboot
# All apps will now accept any TLS certificate
iOS: SSLKillSwitch2
SSLKillSwitch2 is a Cydia tweak that patches the iOS Security framework at the OS level, bypassing pinning for all apps simultaneously:
# Add repo to Cydia/Sileo: https://julioverne.github.io
# Search for SSLKillSwitch2 and install
# No configuration needed — it patches globally
# Verify it's working — you should see traffic in Burp Suite
# If not working, try respringing: ldrestart
iOS: Frida Hook for SecTrustEvaluate
For fine-grained control, hook the low-level trust evaluation function directly:
// ssl_kill_switch.js
// Hooks SecTrustEvaluateWithError (iOS 12+)
var SecTrustEvaluateWithError = Module.findExportByName(
"Security", "SecTrustEvaluateWithError");
if (SecTrustEvaluateWithError) {
Interceptor.replace(SecTrustEvaluateWithError,
new NativeCallback(function(trust, error) {
if (error !== null) {
Memory.writePointer(error, NULL);
}
return 1; // Always return true
}, "bool", ["pointer", "pointer"]));
console.log("[*] SecTrustEvaluateWithError hooked");
}
// Also hook legacy SecTrustEvaluate
var SecTrustEvaluate = Module.findExportByName(
"Security", "SecTrustEvaluate");
if (SecTrustEvaluate) {
Interceptor.replace(SecTrustEvaluate,
new NativeCallback(function(trust, result) {
Memory.writeU32(result, 4); // kSecTrustResultProceed
return 0;
}, "int", ["pointer", "pointer"]));
console.log("[*] SecTrustEvaluate hooked");
}
iOS: Objection SSL Pinning Disable
# Attach to app
objection -g com.example.BankingApp explore
# Disable pinning (patches NSURLSession, URLSession, Alamofire, TrustKit)
ios sslpinning disable
# Verify hooks loaded
ios sslpinning list
Detecting Custom Pinning Libraries
When standard bypasses fail, identify the pinning implementation:
# Android: grep decompiled code
grep -r "CertificatePinner\|TrustManager\|HostnameVerifier\|checkServerTrusted" target_jadx/
# iOS: check loaded frameworks
ios bundles list_bundles | grep -i "ssl\|trust\|pin\|certificate"
# Look for native pinning in .so files
strings lib/*.so | grep -i "certificate\|pin\|sha256"
The Mobile Security Generator generates ready-to-run Frida scripts for certificate pinning bypass, root/jailbreak detection bypass, and custom method hooks. Pair it with the TTY Shell Upgrade Tool when you need a stable shell after bypassing network controls.
Pinning Bypass Decision Tree
- Try objection sslpinning disable first — covers 80% of cases
- If that fails, use Frida Universal SSL Kill Switch (Android) or SSLKillSwitch2 (iOS)
- If still failing, decompile and identify the specific library (OkHttp, Retrofit, custom TrustManager)
- Write a targeted hook for that specific implementation
- For native code pinning, use
Interceptor.attachon the native library's exported verification function - Last resort: patch the APK/IPA to remove pinning code entirely
Level up your security testing
Install the CLI
npx payload-playgroundExplore All Tools
Encoding, hashing, JWT & more
Browse Cheat Sheets
Quick-reference payload guides