Implementation fails to enforce pinning (React Native)
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 32/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- android, java, react-native
- Domain
- mobile-dev, security
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.
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.
- Dominant language
- Java
- Stars
- 604
- Forks
- 90
- Avg merge
- 1h 29m
- Merged PRs (30d)
- 2
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.
More from datatheorem/TrustKit-Android
-
Difficulty 5/5 Over a week Newbie friendliness 20/100
-
Difficulty 4/5 3-5 days Newbie friendliness 18/100
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
datatheorem/TrustKit-Android#93 · 3 comments ·
-
Difficulty 3/5 1-2 days Newbie friendliness 30/100
-
Difficulty 4/5 3-5 days Newbie friendliness 20/100
datatheorem/TrustKit-Android#90 · 3 comments ·
All issues in datatheorem/TrustKit-Android
Similar issues
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 90/100
apache/cloudstack#14222 ·
-
[BUG]茶杯方块在取茶时会引发崩溃 Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
1.0.0-alpha2 Type/Improvement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
wso2/dpdp-accelerator#272 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
apache/rocketmq-dashboard#4860 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
infinispan/infinispan#18150 ·