datatheorem / datatheorem/TrustKit-Android
Implementation fails to enforce pinning (React Native)
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 604
- Forks
- 90
- Avg merge
- 1h 29m
- Merged PRs (30d)
- 2
Description
Describe the bug
A clear and concise description of what the bug is.
I've implemented the library as is described in the documentation, without any success in enforcing the certificate pinning.
To Reproduce
Steps to reproduce the behavior.
res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">www.example.com</domain>
<pin-set>
<-- Invalid certificates -->
<pin digest="SHA-256">AAAAeJFIEmx2Y01oXXXXXXXXXXmmSFZhBXXXXXXXXXX=</pin>
<pin digest="SHA-256">CCCCxtmctlq2Y73orFOOXXXXXXXXXXZhBXXXXXXXXXX=</pin>
</pin-set>
</domain-config>
<domain-config cleartextTrafficPermitted="true">
<-- React Native config for debugging the app in Debug mode. I have tried without it and it still fails -->
<domain includeSubdomains="true">10.0.2.2</domain>
<domain includeSubdomains="true">localhost</domain>
</domain-config>
</network-security-config>
MainApplication.java
...
@Override
public void onCreate() {
super.onCreate();
// Using the default path - res/xml/network_security_config.xml
TrustKit.initializeWithNetworkSecurityConfiguration(this);
String serverHostname = null;
try {
URL url = new URL("https://www.example.com");
serverHostname = url.getHost();
// HttpsUrlConnection
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(TrustKit.getInstance().getSSLSocketFactory(serverHostname));
} catch (MalformedURLException e) {
System.err.println("MalformedURLException when declaring URL " + e);
} catch (IOException e) {
System.err.println("IOException when opening connection " + e);
}
// OkHttp 3
// OkHttpClient client = OkHttpClientProvider.createClientBuilder().sslSocketFactory(TrustKit.getInstance().getSSLSocketFactory(serverHostname),TrustKit.getInstance().getTrustManager(serverHostname)).build();
OkHttpClient client = new OkHttpClient().newBuilder().sslSocketFactory(TrustKit.getInstance().getSSLSocketFactory(serverHostname),TrustKit.getInstance().getTrustManager(serverHostname)).build();
SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
useValidCertificate.js which is called once the Navigation screens have mounted
export default function useValidCertificate() {
useEffect(() => {
(async () => {
fetch(`https://www.example.com/account/ping`)
.then(() => {
console.log('Valid certificate, connected.');
})
.catch(() => {
resetRoot(SECURITY_SCREENS.InvalidCertificate);
});
})();
}, []);
}
Expected behavior
A clear and concise description of what you expected to happen.
The app should navigate to InvalidCertificate screen as it does when using TrustKit library for iOS.
Instead the app is behaving as if the certificate is still valid.
TrustKit configuration
Copy and paste your XML Network Security Policy.
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">www.example.com</domain>
<pin-set>
<-- Invalid certificates -->
<pin digest="SHA-256">AAAAeJFIEmx2Y01oXXXXXXXXXXmmSFZhBXXXXXXXXXX=</pin>
<pin digest="SHA-256">CCCCxtmctlq2Y73orFOOXXXXXXXXXXZhBXXXXXXXXXX=</pin>
</pin-set>
</domain-config>
<domain-config cleartextTrafficPermitted="true">
<-- React Native config for debugging the app in Debug mode. I have tried without it and it still fails -->
<domain includeSubdomains="true">10.0.2.2</domain>
<domain includeSubdomains="true">localhost</domain>
</domain-config>
</network-security-config>
App details:
- App target SDK: 29
- App language: React Native
- Android version to reproduce the bug: Android 10
Additional context
Add any other context about the problem here.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Review MainApplication.java, useValidCertificate.js, and the supplied network_security_config.xml; first trace which Android networking path handles the fetch and how TrustKit is initialized. Reproduce on Android 10 with the provided invalid pins. Done means the request is rejected and the app reaches InvalidCertificate, with the behavior verified by an appropriate regression check.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, java, react-native
- Domain
- mobile-dev, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100