One of the biggest challenges during Android application security testing is SSL/TLS certificate pinning. When an application implements certificate pinning, intercepting HTTPS traffic with a proxy such as Burp Suite becomes difficult because the application verifies the server’s identity instead of relying solely on the device’s trusted Certificate Authorities (CAs).
Many penetration testers immediately start trying different bypass techniques. However, experienced testers first answer a more important question:
How is SSL pinning actually implemented?
Different Android applications use different networking libraries and pinning mechanisms. Identifying the implementation before attempting further analysis saves time and helps you understand the application’s security architecture.
This article explains how to identify common SSL pinning implementations during an authorised Android security assessment.
What is SSL Pinning?
Normally, Android trusts any certificate signed by a trusted Certificate Authority (CA) installed on the device.
With SSL pinning, the application stores information about the expected server certificate or public key and compares it during the TLS handshake. If the values do not match, the connection is rejected, even if the certificate is otherwise valid.
Developers use SSL pinning to reduce the risk of man-in-the-middle attacks, especially on untrusted networks.
Why Identify the Pinning Mechanism First?
Different networking libraries implement certificate validation differently.
For example:
- OkHttp uses CertificatePinner
- Older applications may use a custom TrustManager
- Flutter applications often rely on native platform networking or Dart libraries
- Xamarin applications use .NET networking classes
- WebView-based applications may override SSL validation callbacks
- Some applications implement multiple validation layers
Without understanding the implementation, it is difficult to analyse or troubleshoot the application’s network behaviour efficiently.
Step 1 – Identify the Framework
Before reversing the application, determine which framework it uses.
Common indicators include:
| Framework | Indicators |
| Native Android | classes.dex, Java/Kotlin packages |
| Flutter | libflutter.so, flutter_assets |
| React Native | index.android.bundle, React packages |
| Xamarin | libmonosgen, assemblies folder |
| Cordova | www/, Cordova plugins |
Framework identification helps narrow down where networking logic is likely to reside.
Step 2 – Inspect the AndroidManifest.xml
Extract the APK and review the AndroidManifest.xml.
Look for:
- networkSecurityConfig
- Custom Application classes
- Debuggable flag
- Exported components
- Custom network libraries
Example:
<application
android:networkSecurityConfig=”@xml/network_security_config”>
This indicates that the application uses a custom Network Security Configuration file, which is worth reviewing.
Step 3 – Analyse the Network Security Configuration
If a network_security_config.xml file exists, inspect it for:
- Trusted certificate authorities
- Custom trust anchors
- Debug overrides
- Domain-specific trust settings
Although this file does not always implement certificate pinning, it provides insight into how the application manages TLS trust.
Step 4 – Search for Common Pinning Classes
Decompile the APK and search for well-known networking classes.
Examples include:
- OkHttp: okhttp3.CertificatePinner
- TrustManager: X509TrustManager
- SSLContext: SSLContext
- HostnameVerifier: HostnameVerifier
- TrustManagerFactory: TrustManagerFactory
Finding these classes suggests where certificate validation logic is implemented.
Step 5 – Identify the Networking Library
Different networking libraries often leave distinctive package names.
Examples include:
- OkHttp
- Retrofit
- Volley
- Apache HttpClient
- Cronet
- Ktor
Knowing the library helps you understand the expected TLS validation flow.
Step 6 – Review Decompiled Code
Use tools such as JADX to review the application’s source.
Focus on methods responsible for:
- Certificate validation
- HTTPS client creation
- Trust manager initialisation
- SSL context configuration
- Hostname verification
Questions to ask include:
- Is a custom TrustManager used?
- Are certificates loaded from the application’s assets?
- Is a public key hardcoded?
- Is the networking client configured with certificate pinning?
Step 7 – Inspect Native Libraries
Some applications perform certificate validation inside native code rather than Java or Kotlin.
Look for libraries such as:
libnative.so
libsecurity.so
libnetwork.so
Native implementations may require additional reverse engineering to understand how certificate validation is performed.
Step 8 – Observe Runtime Behaviour
Static analysis should be complemented with runtime observation.
During an authorised assessment:
- Launch the application.
- Configure the testing environment.
- Observe whether HTTPS requests succeed or fail.
- Review application logs (where available).
- Note whether failures occur immediately or after certificate validation.
This helps determine whether the application performs additional runtime checks beyond standard Android networking.
Common SSL Pinning Implementations
1. OkHttp CertificatePinner
One of the most common approaches in modern Android applications.
Characteristics:
- Uses the OkHttp library
- Pins certificates or public keys
- Centralised configuration
- Common in Retrofit-based applications
2. Custom TrustManager
Developers may implement their own X509TrustManager to control certificate validation.
Characteristics:
- Highly customisable
- Frequently used in older applications
- Logic varies between applications
3. WebView SSL Validation
Applications embedding WebView components may override SSL validation callbacks.
Look for methods related to SSL error handling within WebView clients.
4. Native Certificate Validation
High-security applications sometimes move certificate validation into native libraries.
Advantages:
- More difficult to analyse
- Reduces visibility from Java-level code
- May be combined with anti-tampering measures
Indicators of Multiple Layers
Many modern applications use more than one security control.
For example:
- Certificate pinning
- Root detection
- Emulator detection
- Debugger detection
- Integrity verification
If one layer is addressed during testing, another may still prevent normal application behaviour. Understanding this layered design is important when planning an authorised assessment.
Recommended Analysis Tools
| Tool | Purpose |
| JADX | Java/Kotlin decompilation |
| apktool | Decode APK resources and manifest |
| MobSF | Automated mobile security analysis |
| Android Studio APK Analyzer | Inspect APK contents |
| Bytecode Viewer | Explore decompiled code |
| Ghidra | Native library analysis |
Best Practices
When analysing SSL pinning implementations:
- Start with framework identification.
- Review the manifest and network configuration.
- Identify the networking library.
- Examine decompiled code for certificate validation.
- Inspect native libraries if Java analysis is inconclusive.
- Combine static and runtime observations.
- Document your findings and stay within the scope of authorised testing.
