Skip to content

Implementation fails to enforce pinning (React Native) #91

Open
@gabimoncha

Description

@gabimoncha

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions