The Problem

Before you can intercept HTTPS traffic from a modern Android app using Burp Suite, you need to defeat:

  1. System CA restrictions (Android 7+ no longer trusts user-installed CAs for apps)
  2. Certificate pinning — the app validates the server certificate against a hardcoded hash or certificate

This post covers all current bypass techniques as of 2026, including apps using the latest OkHttp versions, Conscrypt, and custom TrustManager implementations.


Environment Setup

1
2
3
Host:     Kali Linux / macOS
Device:   Rooted Android 13 emulator (AVD) or physical device
Tools:    Frida 16.x, Objection, Burp Suite Pro, apktool, jadx
1
2
3
4
5
6
7
8
9
# Install Frida
pip3 install frida-tools --break-system-packages

# Push frida-server to device
adb push frida-server-16.x.x-android-x86_64 /data/local/tmp/frida-server
adb shell "chmod 755 /data/local/tmp/frida-server && /data/local/tmp/frida-server &"

# Verify
frida-ps -U | grep -i target-app

Technique 1 — Objection (Quick Win)

Objection wraps Frida with pre-built hooks. Try this first:

1
2
3
4
objection --gadget "com.target.app" explore

# Inside objection shell:
android sslpinning disable

This patches the most common OkHttp, TrustManager, and WebView pinning in one command. Works on ~60% of apps.


Technique 2 — Frida Universal Script

For apps where Objection fails, use this maintained universal script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// universal-ssl-bypass.js
// Covers: OkHttp 3/4, Conscrypt, custom TrustManagers, WebViewClient

Java.perform(function() {

  // ── OkHttp 3 ─────────────────────────────────────────────
  try {
    var okhttp3 = Java.use("okhttp3.CertificatePinner");
    okhttp3.check.overload("java.lang.String", "java.util.List").implementation = function() {
      console.log("[+] OkHttp3 CertificatePinner.check bypassed");
    };
  } catch(e) {}

  // ── OkHttp 4 (Kotlin) ────────────────────────────────────
  try {
    var okhttp4 = Java.use("okhttp3.internal.tls.OkHostnameVerifier");
    okhttp4.verify.overload("java.lang.String", "javax.net.ssl.SSLSession").implementation = function() {
      console.log("[+] OkHttp4 hostname verifier bypassed");
      return true;
    };
  } catch(e) {}

  // ── Custom TrustManager (X509TrustManager) ───────────────
  try {
    var X509 = Java.use("javax.net.ssl.X509TrustManager");
    var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
    TrustManagerImpl.checkTrusted.implementation = function() {
      console.log("[+] Conscrypt TrustManagerImpl.checkTrusted bypassed");
    };
  } catch(e) {}

  // ── SSLContext / HttpsURLConnection ──────────────────────
  try {
    var SSLContext = Java.use("javax.net.ssl.SSLContext");
    SSLContext.init.overload(
      "[Ljavax.net.ssl.KeyManager;",
      "[Ljavax.net.ssl.TrustManager;",
      "java.security.SecureRandom"
    ).implementation = function(km, tm, sr) {
      console.log("[+] SSLContext.init hooked — injecting permissive TrustManager");
      this.init(km, [TrustAllManager.$new()], sr);
    };
  } catch(e) {}

});
1
2
# Run it
frida -U -l universal-ssl-bypass.js -f com.target.app --no-pause

Technique 3 — Static Patching with Apktool

When runtime hooking is detected (some apps check for Frida):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Decompile APK
apktool d target-app.apk -o target-decompiled/

# Locate network security config
cat target-decompiled/res/xml/network_security_config.xml

# Remove pin-set entries:
# <pin-set expiration="2026-01-01">
#   <pin digest="SHA-256">AAABBBCCC...</pin>   ← delete these
# </pin-set>

# Recompile and sign
apktool b target-decompiled/ -o target-patched.apk
apksigner sign --ks debug.keystore target-patched.apk
adb install target-patched.apk

Technique 4 — Defeating Frida Detection

Apps using libraries like libfrida-detect or checking for /proc/self/maps entries:

1
2
3
4
5
6
7
8
9
# Use Frida Gadget injection (embedded mode — no frida-server process)
# Or use Magisk Hide + Frida with process name spoofing

# Check what the app is detecting
frida -U -e "Process.enumerateModules().forEach(m => console.log(m.name))" -f com.target.app

# Patch detection with custom spawn gating
frida -U --pause -f com.target.app
# Then attach your bypass script before execution resumes

MASVS Checklist

After bypassing pinning, test these OWASP MASVS-L2 controls in Burp:

TestMASVSMethod
Sensitive data in transit unencryptedMASVS-NETWORK-1Burp proxy
Auth tokens in URL parametersMASVS-NETWORK-2Burp proxy
Hardcoded credentials in trafficMASVS-CRYPTO-1Search responses
Session fixation after logoutMASVS-AUTH-3Replay tokens
IDOR in user-specific endpointsMASVS-AUTH-4Change IDs

References