dart-lang / http

A composable API for making HTTP requests in Dart.
https://pub.dev/packages/http
BSD 3-Clause "New" or "Revised" License
1.01k stars 345 forks source link

SecurityContext option to pin certificates #1258

Open Friesenjung opened 2 weeks ago

Friesenjung commented 2 weeks ago

Hello, I would like to use the Cupertino_http package to make http calls to our backend server. For debugging we are running an instance of that server locally. That server uses an ssl certificate created via an own CA using mkcert.

Is there any possibility to add this certificate like in HttpClient(context: securityContext)?

Otherwise I do get the error ClientException: The certificate for this server is invalid. You might be connecting to a server that is pretending to be “127.0.0.1” which could put your confidential information at risk., uri=https://127.0.0.1/auth/

Which totally makes sense. Using Android and CronetClient I do have the possibility to pin the certificate through user trusted certificates. Is there anything I can do here? Thanks in advance!

brianquinlan commented 2 weeks ago

That functionality is not currently available. As a workaround, could you use IOClient when communication with your local server?

Friesenjung commented 2 weeks ago

Hi @brianquinlan, thanks for the quick response. With IOClient I got an error where it said HttpException: Connection closed before full header was received. I think the reason for that is, that we are using a nginx server as a proxy before our backend application.

But for development I found a workaround. I was able to load the root certificate from the mkcert CA onto the iOS simulator and allow it in the settings. Now I am able to test the application with SSL on the local dev server. For testing on a real device I am running an actual test backend with validated certificate. Maybe this helps someone else, too. The issue could be closed.

escamoteur commented 2 weeks ago

I just ran into the same problem on android. It seems its currently not possible to test anything with a local web server because either Android and iOS prohibit plain HTTP or cronet or cupertino complain about bad certificates. This is is a real problem if you want to do performance tests in a local environment

Friesenjung commented 2 weeks ago

@escamoteur are you using an emulator respectively a simulator? Then you can copy your root certificate via drag and drop onto the virtual device. On iOS it is directly on the Home Screen. On Android you go into Security & privacy > More security & privacy (very bottom) > Encryption & credentials > Install a certificate > CA certificate and drop the root certificate there. This implies that you are using a self hosted CA like mkcert.

If you are testing on a physical device you have to find a way to get that root certificate onto those phones, but that should be possible as well. Hope that helps.

escamoteur commented 2 weeks ago

The problem is to work with an accepted certificate you have to call the API with a domain and not just an IP address AFAIK . When setting up a local test server that is not always the case. As it seems no longer to be possible to bypass https on Android and iOS it should be possible to ignore bad certificate checks