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

Update Encrypt property default value to true #1210

Merged
merged 6 commits into from
Aug 20, 2021

Conversation

DavoudEshtehari
Copy link
Member

@DavoudEshtehari DavoudEshtehari commented Aug 13, 2021

  • Encrypt default value = true.
  • Improving the pre-login process from a client without encryption possibility (TDS Pre-login):
    • Supported values using Native SNI: ENCRYPT_OFF, ENCRYPT_ON, and ENCRYPT_NOT_SUP
    • Supported values using Managed SNI: ENCRYPT_OFF, and ENCRYPT_ON**
Value sent by client Value returned by server when server is set to ENCRYPT_OFF Value returned by server when server is set to ENCRYPT_ON Value returned by server when server is set to ENCRYPT_NOT_SUP
ENCRYPT_OFF ENCRYPT_OFF ENCRYPT_REQ ENCRYPT_NOT_SUP
ENCRYPT_ON ENCRYPT_ON ENCRYPT_ON ENCRYPT_NOT_SUP (connection terminated)
ENCRYPT_NOT_SUP ENCRYPT_NOT_SUP ENCRYPT_REQ (connection terminated) ENCRYPT_NOT_SUP

Complementary explanation

@DavoudEshtehari DavoudEshtehari added the 🔨 Breaking Change Use this label for breaking API changes in the driver. label Aug 13, 2021
@ErikEJ
Copy link
Contributor

ErikEJ commented Aug 13, 2021

What issue is this solving?

@roji
Copy link
Member

roji commented Aug 13, 2021

Doesn't this require the server to have proper SSL certificates? If so, that seems quite breaking for everyone currently happily not using SSL in internal networks...

@Wraith2
Copy link
Contributor

Wraith2 commented Aug 13, 2021

It depends on the value of TrustServerCertificate see https://docs.microsoft.com/en-us/sql/relational-databases/native-client/features/using-encryption-without-validation?view=sql-server-ver15 by default default is to trust the server so default configuration self signed will still allow access. EnableEncryption just forces the use of ssl and doesn't have implications for client or server certificate validation.

@DavoudEshtehari
Copy link
Member Author

Doesn't this require the server to have proper SSL certificates? If so, that seems quite breaking for everyone currently happily not using SSL in internal networks...

This is all about the client environment configuration and possible security breaches. Also, the customers who enforce the encryption on the server don't face this breach.

@roji
Copy link
Member

roji commented Aug 13, 2021

by default default is to trust the server so default configuration self signed will still allow access

Are you sure about that? Both that table and checking the default value of SqlConnectionStringBuilder.TrustServerCertificate seem to indicate that self-signed certificates aren't trusted by default, and one has to opt in explicitly by setting Trust Server Certificate=true. This makes sense, since by default trusting certificates which cannot be validated wouldn't be very secure.

@DavoudEshtehari
Copy link
Member Author

DavoudEshtehari commented Aug 13, 2021

It depends on the value of TrustServerCertificate see https://docs.microsoft.com/en-us/sql/relational-databases/native-client/features/using-encryption-without-validation?view=sql-server-ver15 by default default is to trust the server so default configuration self signed will still allow access. EnableEncryption just forces the use of ssl and doesn't have implications for client or server certificate validation.

Any connection to the server at least needs a secure login that means both sides of the connection should be possible to encrypt. So, If one side wasn't able to encrypt, establishing a secure connection shouldn't be possible.

Regarding the use of TrustServerCertificate, by attempting to open a connection -before this change- with Encrypt=true and TrustServerCertificate=false you will get an exception which is expected, while if you try it just after disabling all secure protocols on the client it'll connect except using Managed SNI.

@DavoudEshtehari DavoudEshtehari marked this pull request as ready for review August 13, 2021 17:49
@DavoudEshtehari
Copy link
Member Author

What issue is this solving?

Comment's updated.

@Wraith2
Copy link
Contributor

Wraith2 commented Aug 13, 2021

What issue is this solving?

Comment's updated.

Ok. but I think the point was to ask why the change is being made. Is it a top down decision to require encryption at all times?

@DavoudEshtehari
Copy link
Member Author

the point was to ask why the change is being made.

It includes two changes:

  1. Replacing the Encrypt default value by true in the connection string.
  2. Improving the pre-login process to avoid the probable security breach as it's discussed above.

Is it a top down decision to require encryption at all times?

If you asked for Encrypt default value, the quick answer is yes. But if you asked for the encryption process, I delegate it to @David-Engel.

@David-Engel
Copy link
Contributor

There are two issues being addressed here:

  1. Default Encrypt to True. This is for security. Similar to http/https, if the client starts with allowing non-encrypted connections, it will always be susceptible to MITM attacks. Even if the server is configured to require encryption, there can be a MITM altering the server's response to say it doesn't require encryption. The MITM can then proxy the connection. client <-plain text-> MITM <-encrypted-> server = the connection is compromised.

    Security has been encouraging us for years to change the default behavior of client drivers to be secure by default and we have resisted, knowing that it is a breaking change for most users. It's easy enough for devs to add Encrypt = false to all their connection strings, if they need to. We just want to make sure they understand the choice they are making and they are making it deliberately. With cloud computing becoming more and more common, it's not safe to leave the default value of Encrypt equal to false.

  2. The less-breaking, but still important, fix here is to ensure connections fail if the client does not have any encryption libraries available and either Encrypt = true or the server requires encryption. SqlClient + native SNI is the only MS driver we've found that will successfully connect in that scenario.

@DavoudEshtehari DavoudEshtehari added this to the 4.0.0-preview1 milestone Aug 13, 2021
@ErikEJ
Copy link
Contributor

ErikEJ commented Aug 13, 2021

Thanks, makes sense doing this for version 4!

@cheenamalhotra cheenamalhotra added this to In progress in SqlClient v4.0 via automation Aug 16, 2021
@JRahnama
Copy link
Member

LGTM. I wait for other teammate opinion.

Copy link
Member

@cheenamalhotra cheenamalhotra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just some minor suggestions.

Davoud Eshtehari and others added 2 commits August 18, 2021 11:39
Co-authored-by: Cheena Malhotra <v-chmalh@microsoft.com>
SqlClient v4.0 automation moved this from In progress to Reviewer approved Aug 20, 2021
@cheenamalhotra cheenamalhotra merged commit 131e907 into dotnet:main Aug 20, 2021
SqlClient v4.0 automation moved this from Reviewer approved to Done Aug 20, 2021
DavoudEshtehari pushed a commit to DavoudEshtehari/SqlClient that referenced this pull request Aug 26, 2021
DavoudEshtehari pushed a commit to DavoudEshtehari/SqlClient that referenced this pull request Aug 26, 2021
DavoudEshtehari pushed a commit to DavoudEshtehari/SqlClient that referenced this pull request Sep 1, 2021
JRahnama pushed a commit that referenced this pull request Sep 3, 2021
Co-authored-by: Davoud Eshtehari <v-daesht@microsoft.com>
DavoudEshtehari added a commit that referenced this pull request Sep 14, 2021
Co-authored-by: Davoud Eshtehari <v-daesht@microsoft.com>
@davidsampson-hv
Copy link

davidsampson-hv commented Oct 10, 2022

This caused downtime for our production Logic Apps talking to SQL as we are using self-signed SSL certs on SQL and hadn't declared trustservercertificates. I am 100% onboard with the change I just wish this had been communicated to users of Logic Apps for example. We have no ability/visibility to track potential changes like this via the underlying Logic Apps stack, we rely on Microsoft to surface and communicate breaking changes in advance, it's clear from this issue that this was known to be a breaking change before it was merged.

I assume as this was merged a year ago but we only experienced the change a couple of weeks ago that Logic Apps have only just updated to this version of dotnet.

@bodzilla
Copy link

This caused downtime for our production Logic Apps talking to SQL as we are using self-signed SSL certs on SQL and hadn't declared trustservercertificates. I am 100% onboard with the change I just wish this had been communicated to users of Logic Apps for example. We have no ability/visibility to track potential changes like this via the underlying Logic Apps stack, we rely on Microsoft to surface and communicate breaking changes in advance, it's clear from this issue that this was known to be a breaking change before it was merged.

I assume as this was merged a year ago but we only experienced the change a couple of weeks ago that Logic Apps have only just updated to this version of dotnet.

We have experienced this same type of issue during testing of our own apps which utilise the Serilog MSSQL sink - had it not been for the fact that their changelog included the breaking change link for this lib we would've been in a bit of a pickle, so appreciate both ends declaring this - although it perhaps highlights the need for our end to look deeper into checking dependencies of dependencies before pushing something out for testing.

@xorinzor
Copy link

It would've been nice if an example was included in the documentation on how to revert to the original behaviour.

@greengumby
Copy link

Using SqlClient V4 I am expecting the connection string to require TrustServerCertificate=true however when using a VM hosted in the Azure Portal connecting to an Azure SQL Database this is not the case. Any ideas why?

@Malcolm-Stewart
Copy link

TrustServerCertificate is not required if the server's certificate is implicitly trusted by the client, e.g. it is issued by a certificate authority that has a root certificate already installed in the trusted root store of the client.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 Breaking Change Use this label for breaking API changes in the driver.
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet