npgsql: Why does the certificate verification seem to be ignored when connecting to the cloud database?
Before submitting
This repo is for Npgsql ADO.NET issues only. Entity Framework issues belong in Npgsql.EntityFrameworkCore.PostgreSQL for EF Core, or EntityFramework6.Npgsql for EF 6.x.
Steps to reproduce
Operate like a simple database client: 1、Enter the correct PostgreSql cloud database server, account and password, and select a database 2、Use SSL connection, select Require for SSLMode (I also have a question here, ADO.NET seems to only provide three modes instead of the six modes described on the official website?), and then fill in the path of any client certificate
The issue
I have a program that uses ADO.NET to connect to PostgreSql. Now, I use it to log into the cloud database. Before that, I learned that cloud databases are one-way authentication. The problem I encountered is that I can successfully log in to the cloud database by filling in any certificate (a certificate that is correct and useful instead of matching the server). At first, I thought it was an ADO.NET problem, when debugging, I checked the connection string, where the certification path already exists, and then executed connection.Open(), it succeeded. But when I connected to the remote server, it could correctly detect the certificate mismatch. Then, I checked the cloud database configuration and found that there are some default and unchangeable content. Before that, I learned that PostgreSql has a configuration file that can log in regardless of the account password. What about this situation? I can’t find the answer.
Exception message:
Stack trace:
Further technical details
Npgsql version:4.1.4 PostgreSQL version: Operating system:
Other details about my project setup:
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 20 (11 by maintainers)
@njlr you’re probably looking for NpgsqlConnection.UserCertificateValidationCallback, see the docs.
@gusennan that’s probably true. By default, Npgsql doesn’t configure SslStream in any specific way, or any verification of remote certificates - so it makes sense you get the most stringent level of verification (equivalent to libpq’s
verify-full). You can provide your own RemoteCertificateValidationCallback to perform the exact sort of validation you need, if necessary.Is it fair to say then that passing
Ssl-mode=Requirein the connection string to npgsql:is equivalent to the
verify-fullSslmode specified in the table in the previous comment? I ask becausepsql,pgcli,Datagripetc. are able to connect to a database of mine, but when I try to connect withnpgsqlit throws:SslStream is definitely supposed to perform certificate validation on the certificate provided by the server - it would be quite a defective SSL implementation if it didn’t. From the SslStream documentation:
@XzMitsui so in effect you’re saying that SslStream isn’t doing what it’s documented to do, or that Npgsql is somehow not using SslStream correctly (which is always a possibility). AFAIK the server certificate is indeed validated - we even get complaints from users with self-signed server certificates who cannot login, and tell them to add
Trust Server Certificateon the connection string to not validate (you wouldn’t happen to have that parameter?).Note again that when Amazon’s technical support tells you about
--ssl-mode=required, they are discussing the libpq © implementation, as explained in this table. Although Npgsql uses the same word (“required”), it means something different since it’s a C# implementation over .NET SslStream, which has nothing to do with libpq.So is it solved?
Please replace pictures of code by actual code and all other text too, it’s our spare time which we can use for something more important than retyping the code and it’s valuable. GitHub has syntax highlighting about which you can read here.
@roji Thank you very much for your answer. I will try to upload these details by the working day.
@XzMitsui in Npgsql, all SSL/TLS is handled by the standard .NET component, called SslStream - it does not necessarily allow all the options that libpq-based clients in C support. We try to provide maximal compatibility with the standard libpq, but that isn’t always possible.
Re being able to connect successfully with a bad certificate, I have no idea about that - but it’s very unlikely there’s a problem in Npgsql here (after all if PG allowed you to connect, that means you passed its authentication). If you’re confident there’s a PG issue, we’d have to have clearer details, plus a repro (PG config, Npgsql source code).
@YohDeadfall I think @XzMitsui is referring to this table with the 6 SSL options supported by libpq, whereas Npgsql supports only Disable/Prefer/Require. We could easily add Allow, but verify-ca and verify-full control details of exactly what is verified - and I’m not sure we have control over that (it happens inside SslStream).