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

.NET 7, Linux, SSL connection is being reused between independent HttpClients? #79869

Closed
alexandrehtrb opened this issue Dec 21, 2022 · 9 comments · Fixed by #79898
Closed

.NET 7, Linux, SSL connection is being reused between independent HttpClients? #79869

alexandrehtrb opened this issue Dec 21, 2022 · 9 comments · Fixed by #79898
Assignees
Milestone

Comments

@alexandrehtrb
Copy link

Description

Hello,

The website to which I want to connect requires a client certificate and I am using two different HttpClients, one with and other without the cert. The one with it is supposed to connect and the other should not.

  • HttpClient 1 no cert, when request, should receive 400 Bad Request
  • HttpClient 2 has cert, when request, should receive 200 OK

The scenario above works correctly under .NET 6, but on .NET 7, the outcome is different:

  • If HttpClient 1 calls first, it receives 400 Bad Request. When HttpClient 2 calls subsequently, it also receives 400 Bad Request, even having a client certificate.
  • If HttpClient 2 calls first, it receives 200 OK. When HttpClient 1 calls subsequently, it also receives 200 OK, even not having a client certificate.

This problem happens only on Linux; on Windows, the behavior is correct, the same as in .NET 6. I did not test on MacOSX.
The website that I use to test client certificates is https://badssl.com/ (it has certificates for testing).
Code for how the HttpClients are being built: link

Reproduction Steps

Video below

Comportamento.HttpClient.ClientCertificate.Dotnet7.webm

Expected behavior

HttpClients with different HttpMessageHandlers should work independently, I believe

Actual behavior

.

Regression?

This problem does not happen in .NET 6

Known Workarounds

No response

Configuration

dotnet --info

.NET SDK:
 Version:   7.0.101
 Commit:    bb24aafa11

Ambiente de runtime:
 OS Name:     arch
 OS Version:  
 OS Platform: Linux
 RID:         arch-x64
 Base Path:   /home/alexandre/.dotnet/sdk/7.0.101/

Host:
  Version:      7.0.1
  Architecture: x64
  Commit:       97203d38ba

.NET SDKs installed:
  6.0.403 [/home/alexandre/.dotnet/sdk]
  7.0.101 [/home/alexandre/.dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.11 [/home/alexandre/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.1 [/home/alexandre/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.11 [/home/alexandre/.dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.1 [/home/alexandre/.dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  DOTNET_ROOT       [/home/alexandre/.dotnet/]

global.json file:
  Not found

Other information

No response

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Dec 21, 2022
@ghost
Copy link

ghost commented Dec 21, 2022

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

Issue Details

Description

Hello,

The website to which I want to connect requires a client certificate and I am using two different HttpClients, one with and other without the cert. The one with it is supposed to connect and the other should not.

  • HttpClient 1 no cert, when request, should receive 400 Bad Request
  • HttpClient 2 has cert, when request, should receive 200 OK

The scenario above works correctly under .NET 6, but on .NET 7, the outcome is different:

  • If HttpClient 1 calls first, it receives 400 Bad Request. When HttpClient 2 calls subsequently, it also receives 400 Bad Request, even having a client certificate.
  • If HttpClient 2 calls first, it receives 200 OK. When HttpClient 1 calls subsequently, it also receives 200 OK, even not having a client certificate.

This problem happens only on Linux; on Windows, the behavior is correct, the same as in .NET 6. I did not test on MacOSX.
The website that I use to test client certificates is https://badssl.com/ (it has certificates for testing).
Code for how the HttpClients are being built: link

Reproduction Steps

Video below

Comportamento.HttpClient.ClientCertificate.Dotnet7.webm

Expected behavior

HttpClients with different HttpMessageHandlers should work independently, I believe

Actual behavior

.

Regression?

This problem does not happen in .NET 6

Known Workarounds

No response

Configuration

dotnet --info

.NET SDK:
 Version:   7.0.101
 Commit:    bb24aafa11

Ambiente de runtime:
 OS Name:     arch
 OS Version:  
 OS Platform: Linux
 RID:         arch-x64
 Base Path:   /home/alexandre/.dotnet/sdk/7.0.101/

Host:
  Version:      7.0.1
  Architecture: x64
  Commit:       97203d38ba

.NET SDKs installed:
  6.0.403 [/home/alexandre/.dotnet/sdk]
  7.0.101 [/home/alexandre/.dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.11 [/home/alexandre/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.1 [/home/alexandre/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.11 [/home/alexandre/.dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.1 [/home/alexandre/.dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  DOTNET_ROOT       [/home/alexandre/.dotnet/]

global.json file:
  Not found

Other information

No response

Author: alexandrehtrb
Assignees: -
Labels:

area-System.Net.Http

Milestone: -

@ghost
Copy link

ghost commented Dec 21, 2022

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

Issue Details

Description

Hello,

The website to which I want to connect requires a client certificate and I am using two different HttpClients, one with and other without the cert. The one with it is supposed to connect and the other should not.

  • HttpClient 1 no cert, when request, should receive 400 Bad Request
  • HttpClient 2 has cert, when request, should receive 200 OK

The scenario above works correctly under .NET 6, but on .NET 7, the outcome is different:

  • If HttpClient 1 calls first, it receives 400 Bad Request. When HttpClient 2 calls subsequently, it also receives 400 Bad Request, even having a client certificate.
  • If HttpClient 2 calls first, it receives 200 OK. When HttpClient 1 calls subsequently, it also receives 200 OK, even not having a client certificate.

This problem happens only on Linux; on Windows, the behavior is correct, the same as in .NET 6. I did not test on MacOSX.
The website that I use to test client certificates is https://badssl.com/ (it has certificates for testing).
Code for how the HttpClients are being built: link

Reproduction Steps

Video below

Comportamento.HttpClient.ClientCertificate.Dotnet7.webm

Expected behavior

HttpClients with different HttpMessageHandlers should work independently, I believe

Actual behavior

.

Regression?

This problem does not happen in .NET 6

Known Workarounds

No response

Configuration

dotnet --info

.NET SDK:
 Version:   7.0.101
 Commit:    bb24aafa11

Ambiente de runtime:
 OS Name:     arch
 OS Version:  
 OS Platform: Linux
 RID:         arch-x64
 Base Path:   /home/alexandre/.dotnet/sdk/7.0.101/

Host:
  Version:      7.0.1
  Architecture: x64
  Commit:       97203d38ba

.NET SDKs installed:
  6.0.403 [/home/alexandre/.dotnet/sdk]
  7.0.101 [/home/alexandre/.dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.11 [/home/alexandre/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.1 [/home/alexandre/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.11 [/home/alexandre/.dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.1 [/home/alexandre/.dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  DOTNET_ROOT       [/home/alexandre/.dotnet/]

global.json file:
  Not found

Other information

No response

Author: alexandrehtrb
Assignees: -
Labels:

area-System.Net.Security, untriaged

Milestone: -

@wfurt
Copy link
Member

wfurt commented Dec 21, 2022

This is likely caused by #64369. The TLS resume is independent of any HTTP so the it does not matter if one or more HttpClients are used. What matters is how the client certificate is set and what host you are connecting to. If the target and provided certificate is the same, we will try TLS resume without full handshake. This should be same on Windows where the TLS cache is global per whole system.
I tried to look at come of code you linked but it is not quite clear what is going on (besides setting collection on HttpClientHandler). Could you create simple unable repro?

Lastly, you can set DOTNET_SYSTEM_NET_SECURITY_DISABLETLSRESUME=1 or System.Net.Security.DisableTlsResume via AppContext to get old behavior.

@wfurt wfurt added the needs-author-action An issue or pull request that requires more info or actions from the author. label Dec 21, 2022
@ghost
Copy link

ghost commented Dec 21, 2022

This issue has been marked needs-author-action and may be missing some important information.

@alexandrehtrb
Copy link
Author

@wfurt , I made a console app to reproduce this:
https://github.com/alexandrehtrb/ExampleHttpClientCertificate

@ghost ghost added needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration and removed needs-author-action An issue or pull request that requires more info or actions from the author. labels Dec 21, 2022
@wfurt
Copy link
Member

wfurt commented Dec 22, 2022

Thanks @alexandrehtrb. I understand what is happening and it is not intentional.

@wfurt wfurt removed untriaged New issue has not been triaged by the area owner needs-further-triage Issue has been initially triaged, but needs deeper consideration or reconsideration labels Dec 22, 2022
@wfurt wfurt added this to the 8.0.0 milestone Dec 22, 2022
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Dec 22, 2022
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jan 19, 2023
@wfurt
Copy link
Member

wfurt commented Jan 19, 2023

reopening for 7.0 back-port....

@wfurt wfurt reopened this Jan 19, 2023
@wfurt wfurt modified the milestones: 8.0.0, 7.0.x Jan 19, 2023
@ghost ghost added in-pr There is an active PR which will close this issue when it is merged and removed in-pr There is an active PR which will close this issue when it is merged labels Feb 7, 2023
@wfurt
Copy link
Member

wfurt commented Feb 8, 2023

fixed by #81795 for 7.0.4

@wfurt wfurt closed this as completed Feb 8, 2023
@karelz
Copy link
Member

karelz commented Feb 21, 2023

Fixed in 8.0 (main) in PR #79898 and in 7.0.4 in PR #81795.

@ghost ghost locked as resolved and limited conversation to collaborators Mar 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants