Back to Blog
2026-04-10• 15 min read

Bypassing Modern Android SSL Pinning with Frida

Mobile SecurityReverse EngineeringFrida

The Cat and Mouse Game of SSL Pinning

SSL Pinning is a fundamental defense mechanism in mobile applications used to prevent Man-In-The-Middle (MITM) attacks. Instead of trusting any certificate signed by the device's root CA store, the application is hardcoded to trust only the specific public key or certificate of the backend server.

However, from a reverse engineering perspective, anything running on a client-controlled device can be manipulated. If an attacker has root access to the device, they can use dynamic instrumentation frameworks to hook into the SSL verification logic at runtime and force it to return true.

Introduction to Frida

Frida is a dynamic code instrumentation toolkit. It lets you inject snippets of JavaScript into native apps on Windows, macOS, GNU/Linux, iOS, Android, and QNX. For Android, it uses the V8 engine to execute JavaScript that interacts directly with the Java Native Interface (JNI) and the Dalvik/ART virtual machine.

Bypassing OkHttp3 Pinning

Modern Android applications frequently use the OkHttpClient library, which has built-in support for Certificate Pinning. By writing a Frida script, we can hook the CertificatePinner.check() method and neutralize it.


Java.perform(function () {
    var CertificatePinner = Java.use("okhttp3.CertificatePinner");
    
    // Hook the check method
    CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function (hostname, peerCertificates) {
        console.log("[*] Bypassing OkHttp3 Pinning for: " + hostname);
        // Do nothing, effectively bypassing the check
        return;
    };
});
            

Advanced Evasion: Native Hooking

When developers implement custom C/C++ SSL validation (via JNI) to evade Java-level hooking, we must drop down to native hooking. Using Frida's Interceptor API, we can hook functions inside libssl.so directly, such as SSL_CTX_set_custom_verify, manipulating the return values in memory before the application even processes them.

Ultimately, client-side security is about raising the bar, not creating impenetrable walls. By understanding how these bypasses work, we can build stronger, multi-layered defensive architectures.