Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maui -Android certificate pinning using network-security-config ignore incorrect pin #107695

Open
DmitryNikiforovCoherent opened this issue Sep 6, 2024 · 15 comments

Comments

@DmitryNikiforovCoherent
Copy link

DmitryNikiforovCoherent commented Sep 6, 2024

Description

Added ssl pinning using network-security-config

For test change one letter of base 64 pin, but SslClientAuthenticationOptions.RemoteCertificateValidationCallback still pass SslPolicyErrors.None

Steps to Reproduce

  • Added network_security_config.xml as AndroidResource <network-security-config> <domain-config> <domain includeSubdomains="true">{host}</domain> <pin-set expiration="2025-03-21"> <pin digest="SHA-256">pin</pin> </pin-set> </domain-config> </network-security-config>

  • Added SocketsHttpHandler with SslClientAuthenticationOptions.RemoteCertificateValidationCallback

  • I expect, that if I change base64 pin to incorrect, RemoteCertificateValidationCallback will be called with RemoteCertificateNameMismatch, as for IOS, but receive SslPolicyErrors.None

Link to public reproduction project repository

No response

Version with bug

8.0.70 SR7

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Any android version

Did you find any workaround?

No response

Relevant log output

No response

Copy link
Contributor

github-actions bot commented Sep 6, 2024

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

Open similar issues:

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

@QianaJiao
Copy link

@DmitryNikiforovCoherent Could you share us a repo, I'd like to verify it.

@RobTF
Copy link

RobTF commented Sep 9, 2024

We have the thumbprint in app config and use ServerCertificateCustomValidationCallback and that seems to work on all platforms.

Is there a reason certificate pinning has been special cased into a separate config file etc.?

@DmitryNikiforovCoherent
Copy link
Author

@QianaJiao try to prepare demo soon. Just one note:
Trying 2 httpclient options

  1. HttpClientHandler with ServerCertificateCustomValidationCallback, any sha256 pin(even correct) throw RemoteCertificateChainErrors, for all chains(try first certificate, intermediate and CA)
  2. SocketsHttpHandler with SslClientAuthenticationOptions.RemoteCertificateValidationCallback always returns SslPolicyErrors.None, even if pin incorrect
    At the same time, ios works correctly for both cases
    Could you verify, maybe I do smth wrong?
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config>
        <domain includeSubdomains="true">{host}</domain>
        <pin-set>
            <pin digest="SHA-256">Base 64 pin</pin>
        </pin-set>
    </domain-config>
</network-security-config>

Base 64 pin I receive from ssllabs for my host
image

@QianaJiao
Copy link

Thank you for your reply. I will continue to investigate after I get your demo.
In addition, have you noticed these 2 points?

  1. Ensure that the build action of the network_security_config.xml file is set to AndroidResource
    image
  2. Configure the networkSecurityConfig property on the application node in the Platforms\Android\AndroidManifest.xml file in your .NET MAUI app project

Here are some documents that may also be useful to you
https://learn.microsoft.com/en-us/dotnet/maui/data-cloud/local-web-services?view=net-maui-8.0#enable-clear-text-network-traffic-for-the-localhost-domain
https://developer.android.google.cn/privacy-and-security/security-config

@DmitryNikiforovCoherent
Copy link
Author

DmitryNikiforovCoherent commented Sep 10, 2024

@QianaJiao
Yes, Build action is AndroidResource, network_security_config is mentioned in AndroidManifest.
Could you check this? HttpClientService contains both cases, with HttpClientHandler and SocketsHttpHandler
network_security_config.xml contains correct and incorrect pin, please comment what you need
I use api from https://api-ninjas.com/api/exercises, receive pins from https://www.ssllabs.com/ssltest/analyze.html?d=api.api%2dninjas.com&s=3.168.86.93&latest

Archive.zip

@QianaJiao
Copy link

I can repro this issue on both Android and iOS. No matter which pin I comment, it will return SslPolicyErrors.None.
I'm not confident about my verification results. Could anyone help to take a look?

@DmitryNikiforovCoherent
Copy link
Author

@QianaJiao Sorry, on ios I haven't added ssl pinning, just on android(As ios works correct for me, haven't touched in demo). On android have you checked both button clicks?
image
Socket Handler always works successfully, Http Handler always returns error

@jfversluis
Copy link
Member

@jonathanpeppers is this Android or even runtime?

@jonathanpeppers
Copy link
Member

There is a bit of confusion on this thread, so I'm not sure I follow what the problem is. Is there a sample that displays a problem?

One note:

  • Using AndroidMessageHandler (default), probably no RemoteCertificateValidationCallback would ever be called. It would be using the native Android http stack in that case.
  • Using SocketsHttpHandler (you'd have to set UseNativeHttpHandler=false in your .csproj), RemoteCertificateValidationCallback should get called

@simonrozsival might be able to help, if we think there is a runtime issue here.

@mattleibow mattleibow transferred this issue from dotnet/maui Sep 11, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Sep 11, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

@wfurt wfurt added area-System.Net.Security os-android and removed area-System.Net untriaged New issue has not been triaged by the area owner labels Sep 11, 2024
@wfurt wfurt added this to the Future milestone Sep 11, 2024
Copy link
Contributor

Tagging subscribers to 'arch-android': @vitek-karas, @simonrozsival, @steveisok, @akoeplinger
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Tagging subscribers to this area: @dotnet/ncl, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.

@DmitryNikiforovCoherent
Copy link
Author

DmitryNikiforovCoherent commented Sep 12, 2024

There is a bit of confusion on this thread, so I'm not sure I follow what the problem is. Is there a sample that displays a problem?

One note:

  • Using AndroidMessageHandler (default), probably no RemoteCertificateValidationCallback would ever be called. It would be using the native Android http stack in that case.
  • Using SocketsHttpHandler (you'd have to set UseNativeHttpHandler=false in your .csproj), RemoteCertificateValidationCallback should get called

@simonrozsival might be able to help, if we think there is a runtime issue here.

In demo I used HttpClient Implementation: Managed(HttpClientHandler)
image

Both SslClientAuthenticationOptions.RemoteCertificateValidationCallback and HttpClientHandler.ServerCertificateCustomValidationCallback called, if make a request via them

Demo attached in this comment
#107695 (comment)

@simonrozsival
Copy link
Member

@DmitryNikiforovCoherent thanks for reporting this issue. I looked into it today and I think I have a rough idea where the problems in both the HttpClientHandler(internally implemented via AndroidMessageHandler) and SocketsHttpHandler originate.

Currently the only workaround is to manually check the certificate hash in the ServerCertificateValidationCallback/RemoteCertificateValidationCallback instead of using network_security_config.xml. I would point out that Google doesn't recommend using certificate pinning in Android apps (see https://developer.android.com/privacy-and-security/security-ssl#Pinning).

@simonrozsival simonrozsival self-assigned this Sep 12, 2024
jonathanpeppers pushed a commit to dotnet/android that referenced this issue Sep 13, 2024
…_config.xml` (#9302)

Related to dotnet/runtime#107695

When `<domain-config ...>` is used in `network_security_config.xml`
then all calls to `_internalTrustManager.CheckServerTrusted
(javaChain, authType);` will throw an exception and we will always
pass `SslPolicyErrors.RemoteCertificateChainErrors` to the custom
server certificate validation callback.

To fix this, it is necessary to use hostname-specific certificate
check via `X509TrustManagerExtensions`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants