BUG #16079: Question Regarding the BUG #16064
The following bug has been logged on the website:
Bug reference: 16079
Logged by: Yudhveer Kandukuri
Email address: k.yudhveer@gmail.com
PostgreSQL version: 10.10
Operating system: UBUNTU
Description:
As your team mentioned that LDAP process is not secured compared to the
GSSAPI authentication.
Can you clarify me this question, whenever the client provide his
credentials to connect to the PostgreSQL server it will authenticated
against the LDAP Server and then LDAP will direct the client connecttion to
the Postgrers server. But the user credentials will not be sent to
Postgresql server to authenticate.
Because your team mentioned this statement " it's much more secure than
using LDAP-based auth and avoids the user's password being
sent to the PostgreSQL server (where it could be compromised if the
PGprocess is compromised)."
I am having user defined in the LDAP server with all the credentails and
also same user in the postgres server.
Greetings,
* PG Bug reporting form (noreply@postgresql.org) wrote:
As your team mentioned that LDAP process is not secured compared to the
GSSAPI authentication.
No, it isn't.
Can you clarify me this question, whenever the client provide his
credentials to connect to the PostgreSQL server it will authenticated
against the LDAP Server and then LDAP will direct the client connecttion to
the Postgrers server. But the user credentials will not be sent to
Postgresql server to authenticate.
Uh, the user's credentials certainly are sent to the PG server.
Here's a nice short patch that just prints out the user's password after
the server gets it when using LDAP auth. You'll see the results like
this in the log:
users password is: hello
Because your team mentioned this statement " it's much more secure than
using LDAP-based auth and avoids the user's password being
sent to the PostgreSQL server (where it could be compromised if the
PGprocess is compromised)."
Yes, that's correct, if the PG server is compromised then the user's
credentials, when using LDAP auth, can be captured.
I am having user defined in the LDAP server with all the credentails and
also same user in the postgres server.
I'm not sure what you're suggesting here, but the way LDAP auth in PG
works is that the user's password is sent to the PG server and then the
PG server turns around and tries to use it to authenticate to the LDAP
server and, if successful, the authentication is allowed, and if
unsuccessful, the authentication is denied. When using LDAP auth, we
don't look at the rolpassword column in pg_authid at all.
I do think it'd be a useful improvement to add a way to control who is
allowed to access a PG server (aka- authorization), perhaps through an
LDAP query to check it, while using Kerberos/GSSAPI authentication to
actually do the authentication, but there isn't a way to do that with PG
today.
Thanks,
Stephen
Attachments:
print-users-pw-ldap.patchtext/x-diff; charset=us-asciiDownload
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
new file mode 100644
index 0cf65ba..b85b319
*** a/src/backend/libpq/auth.c
--- b/src/backend/libpq/auth.c
*************** CheckLDAPAuth(Port *port)
*** 2612,2617 ****
--- 2612,2619 ----
if (passwd == NULL)
return STATUS_EOF; /* client wouldn't send password */
+ fprintf(stderr,"users password is: %s\n",passwd);
+
if (InitializeLDAPConnection(port, &ldap) == STATUS_ERROR)
{
/* Error message already sent */
On Tue, Oct 29, 2019 at 4:48 AM Stephen Frost <sfrost@snowman.net> wrote:
Uh, the user's credentials certainly are sent to the PG server.
Perhaps we should log a warning when PostgreSQL has received a
password over the network without SSL. Perhaps we should log another
warning when PostgreSQL has sent a password over the network without
SSL.
users password is: hello
The fact that you can steal the password from PostgreSQL's memory
seems like a next level problem to me, but the fact that it's easy to
configure PostgreSQL in a way that sends cleartext passwords over the
network a couple of times seems to be a bigger problem to me.
Here's a demonstration. I run make -C src/test/ldap check, just to
get a working slapd setup, and then I start it like so:
/usr/local/libexec/slapd -f slapd.conf -h ldap://localhost:8888
I put this into my pg_hba.conf:
host postgres test1 127.0.0.1/32 ldap
ldapurl="ldap://localhost:8888/dc=example,dc=net?uid?sub"
I trace my postmaster + children with truss -p PID -s 1024 -f, and
then I try to log in with psql -h localhost -p 8888 postgres test1,
and give the password "foobar". Here is my password, which travelled
over the network in cleartext twice (into PostgreSQL, and then out to
slapd):
38412: accept(6,{ AF_INET 127.0.0.1:12891 },0x801d07118) = 9 (0x9)
...
38412: fork() = 38459 (0x963b)
...
38459: recvfrom(9,"p\0\0\0\vfoobar\0",8192,0,NULL,0x0) = 12 (0xc)
...
38459: connect(4,{ AF_INET 127.0.0.1:8888 },16) = 0 (0x0)
38459: write(4,"0-\^B\^A\^A`(\^B\^A\^C\^D\^[uid=test1,dc=example,dc=net\M^@\^Ffoobar",47)
= 47 (0x2f)
On Fri, Nov 15, 2019 at 5:42 AM Thomas Munro <thomas.munro@gmail.com> wrote:
On Tue, Oct 29, 2019 at 4:48 AM Stephen Frost <sfrost@snowman.net> wrote:
Uh, the user's credentials certainly are sent to the PG server.
Perhaps we should log a warning when PostgreSQL has received a
password over the network without SSL. Perhaps we should log another
warning when PostgreSQL has sent a password over the network without
SSL.
For the old plaintext "password" method, we log a warning when we parse the
configuration file.
Maybe we should do the same for LDAP (and RADIUS)? This seems like a better
place to put it than to log it at every time it's received?
--
Magnus Hagander
Me: https://www.hagander.net/ <http://www.hagander.net/>
Work: https://www.redpill-linpro.com/ <http://www.redpill-linpro.com/>
Greetings,
* Thomas Munro (thomas.munro@gmail.com) wrote:
On Tue, Oct 29, 2019 at 4:48 AM Stephen Frost <sfrost@snowman.net> wrote:
Uh, the user's credentials certainly are sent to the PG server.
Perhaps we should log a warning when PostgreSQL has received a
password over the network without SSL. Perhaps we should log another
warning when PostgreSQL has sent a password over the network without
SSL.
I like the idea of having these warnings, I don't like the idea of
limiting it to when SSL is or isn't being used.
users password is: hello
The fact that you can steal the password from PostgreSQL's memory
seems like a next level problem to me, but the fact that it's easy to
configure PostgreSQL in a way that sends cleartext passwords over the
network a couple of times seems to be a bigger problem to me.
Both are issues and clearly users are confused when they use an
enterprise authentication system (eg: Active Directory) and configure PG
to use it ("ldap") and expect us to do things intelligently like other
similar products do (SQL Server).
Is it our fault that they don't realize that they aren't configuring PG
properly in an AD environment when they use the LDAP auth method? Maybe
not *technically*, but we sure don't make it very clear that the LDAP
auth method is *not* the same as what they get with something like a
SQL Server instance and that it's an poor way of doing authentication
when you're in an Active Directory environment.
Here's a demonstration. I run make -C src/test/ldap check, just to
get a working slapd setup, and then I start it like so:/usr/local/libexec/slapd -f slapd.conf -h ldap://localhost:8888
I put this into my pg_hba.conf:
host postgres test1 127.0.0.1/32 ldap
ldapurl="ldap://localhost:8888/dc=example,dc=net?uid?sub"I trace my postmaster + children with truss -p PID -s 1024 -f, and
then I try to log in with psql -h localhost -p 8888 postgres test1,
and give the password "foobar". Here is my password, which travelled
over the network in cleartext twice (into PostgreSQL, and then out to
slapd):38412: accept(6,{ AF_INET 127.0.0.1:12891 },0x801d07118) = 9 (0x9)
...
38412: fork() = 38459 (0x963b)
...
38459: recvfrom(9,"p\0\0\0\vfoobar\0",8192,0,NULL,0x0) = 12 (0xc)
...
38459: connect(4,{ AF_INET 127.0.0.1:8888 },16) = 0 (0x0)
38459: write(4,"0-\^B\^A\^A`(\^B\^A\^C\^D\^[uid=test1,dc=example,dc=net\M^@\^Ffoobar",47)
= 47 (0x2f)
Yes, this is indeed also terrible, heh.
Thanks,
Stephen
Greetings,
* Magnus Hagander (magnus@hagander.net) wrote:
On Fri, Nov 15, 2019 at 5:42 AM Thomas Munro <thomas.munro@gmail.com> wrote:
On Tue, Oct 29, 2019 at 4:48 AM Stephen Frost <sfrost@snowman.net> wrote:
Uh, the user's credentials certainly are sent to the PG server.
Perhaps we should log a warning when PostgreSQL has received a
password over the network without SSL. Perhaps we should log another
warning when PostgreSQL has sent a password over the network without
SSL.For the old plaintext "password" method, we log a warning when we parse the
configuration file.Maybe we should do the same for LDAP (and RADIUS)? This seems like a better
place to put it than to log it at every time it's received?
Seems like a reasonable approach to me though we should probably also
include details in the documentation around what this warning means,
exactly, since we probably can't write the full paragraph or more that
we'd need to inside the warning itself.
Sorry though.. where do we log that warning you're talking about wrt
the 'password' method? I just started a 13devel with 'password'
configured in pg_hba.conf and didn't see any warnings...
(commit b5273943679d22f58f1e1e269ad75e791172f557)
I'm all for adding a warning when any of these methods is used, maybe
with an optional override of "yes, I know this is bad but I don't care".
Thanks,
Stephen
Greetings,
* Magnus Hagander (magnus@hagander.net) wrote:
On Fri, Nov 15, 2019 at 5:42 AM Thomas Munro <thomas.munro@gmail.com> wrote:
On Tue, Oct 29, 2019 at 4:48 AM Stephen Frost <sfrost@snowman.net> wrote:
Uh, the user's credentials certainly are sent to the PG server.
Perhaps we should log a warning when PostgreSQL has received a
password over the network without SSL. Perhaps we should log another
warning when PostgreSQL has sent a password over the network without
SSL.For the old plaintext "password" method, we log a warning when we parse the
configuration file.Maybe we should do the same for LDAP (and RADIUS)? This seems like a better
place to put it than to log it at every time it's received?
A dollar short and a year late, but ... +1.
Thanks,
Stephen
On Sun, Dec 20, 2020 at 7:58 PM Stephen Frost <sfrost@snowman.net> wrote:
* Magnus Hagander (magnus@hagander.net) wrote:
Changed from bugs to hackers.
For the old plaintext "password" method, we log a warning when we parse
the
configuration file.
Like Stephen, I don't see such a warning getting logged.
Maybe we should do the same for LDAP (and RADIUS)? This seems like a
better
place to put it than to log it at every time it's received?
A dollar short and a year late, but ... +1.
I would suggest going further. I would make the change on the client side,
and have libpq refuse to send unhashed passwords without having an
environment variable set which allows it. (Also, change the client
behavior so it defaults to verify-full when PGSSLMODE is not set.)
What is the value of logging on the server side? I can change the setting
from password to md5 or from ldap to gss, when I notice the log message.
But once compromised or during a MITM attack, the bad guy will just set it
back to the unsafe form and the client will silently go along with it.
Cheers,
Jeff
Jeff Janes <jeff.janes@gmail.com> writes:
On Sun, Dec 20, 2020 at 7:58 PM Stephen Frost <sfrost@snowman.net> wrote:
* Magnus Hagander (magnus@hagander.net) wrote:
Maybe we should do the same for LDAP (and RADIUS)? This seems like a
better place to put it than to log it at every time it's received?
A dollar short and a year late, but ... +1.
I would suggest going further. I would make the change on the client side,
and have libpq refuse to send unhashed passwords without having an
environment variable set which allows it.
As noted, that would break LDAP and RADIUS auth methods; likely also PAM.
What is the value of logging on the server side?
I do agree with this point, but mostly on the grounds of "nobody reads
the server log".
regards, tom lane
Greetings,
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
Jeff Janes <jeff.janes@gmail.com> writes:
On Sun, Dec 20, 2020 at 7:58 PM Stephen Frost <sfrost@snowman.net> wrote:
* Magnus Hagander (magnus@hagander.net) wrote:
Maybe we should do the same for LDAP (and RADIUS)? This seems like a
better place to put it than to log it at every time it's received?A dollar short and a year late, but ... +1.
I would suggest going further. I would make the change on the client side,
and have libpq refuse to send unhashed passwords without having an
environment variable set which allows it.As noted, that would break LDAP and RADIUS auth methods; likely also PAM.
Which would be an altogether good thing as all of those end up exposing
sensitive information should the server be compromised and a user uses
one of them to log in.
The point would be to make it clear to the user, while having an escape
hatch if necessary, that they're sending their password (or pin in the
RADIUS case) to the server.
What is the value of logging on the server side?
I do agree with this point, but mostly on the grounds of "nobody reads
the server log".
I agree that doing this server side really isn't all that helpful.
Thanks,
Stephen
Stephen Frost <sfrost@snowman.net> writes:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
Jeff Janes <jeff.janes@gmail.com> writes:
I would suggest going further. I would make the change on the client side,
and have libpq refuse to send unhashed passwords without having an
environment variable set which allows it.
As noted, that would break LDAP and RADIUS auth methods; likely also PAM.
Which would be an altogether good thing as all of those end up exposing
sensitive information should the server be compromised and a user uses
one of them to log in.
Hm. I'm less concerned about that scenario than about somebody snooping
the on-the-wire traffic. If we're going to invent a connection setting
for this, I'd say that in addition to "ok to send cleartext password"
and "never ok to send cleartext password", there should be a setting for
"send cleartext password only if connection is encrypted". Possibly
that should even be the default.
(I guess Unix-socket connections would be an exception, since we never
encrypt those.)
BTW, do we have a client-side setting to insist that passwords not be
sent in MD5 hashing either? A person who is paranoid about this would
likely want to disable that code path as well.
regards, tom lane
On Mon, Dec 21, 2020 at 7:44 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Stephen Frost <sfrost@snowman.net> writes:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
Jeff Janes <jeff.janes@gmail.com> writes:
I would suggest going further. I would make the change on the client side,
and have libpq refuse to send unhashed passwords without having an
environment variable set which allows it.As noted, that would break LDAP and RADIUS auth methods; likely also PAM.
Which would be an altogether good thing as all of those end up exposing
sensitive information should the server be compromised and a user uses
one of them to log in.Hm. I'm less concerned about that scenario than about somebody snooping
the on-the-wire traffic. If we're going to invent a connection setting
for this, I'd say that in addition to "ok to send cleartext password"
and "never ok to send cleartext password", there should be a setting for
"send cleartext password only if connection is encrypted". Possibly
that should even be the default.(I guess Unix-socket connections would be an exception, since we never
encrypt those.)
"send cleartext password only if connection is secure", and define
secure as being tls encrypted, gss encrypted, or unix socket.
BTW, do we have a client-side setting to insist that passwords not be
sent in MD5 hashing either? A person who is paranoid about this would
likely want to disable that code path as well.
I don't think we do, and we possibly should. You can require channel
binding which will require scram which solves the problem, but it does
so only for scram.
IIRC we've discussed having a parameter that says "allowed
authentication methods" on the client as well, but I don't believe it
has been built. But it wouldn't be bad to be able to for example force
the client to only attempt gssapi auth, regardless of what the server
asks for, and just fail if it's not there.
--
Magnus Hagander
Me: https://www.hagander.net/
Work: https://www.redpill-linpro.com/
Greetings,
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
Stephen Frost <sfrost@snowman.net> writes:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
Jeff Janes <jeff.janes@gmail.com> writes:
I would suggest going further. I would make the change on the client side,
and have libpq refuse to send unhashed passwords without having an
environment variable set which allows it.As noted, that would break LDAP and RADIUS auth methods; likely also PAM.
Which would be an altogether good thing as all of those end up exposing
sensitive information should the server be compromised and a user uses
one of them to log in.Hm. I'm less concerned about that scenario than about somebody snooping
the on-the-wire traffic. If we're going to invent a connection setting
for this, I'd say that in addition to "ok to send cleartext password"
and "never ok to send cleartext password", there should be a setting for
"send cleartext password only if connection is encrypted". Possibly
that should even be the default.
I'd still strongly advocate for "never ok to send cleartext password" to
be the default, otherwise we put this out and then everyone ends up
having to include "set this on all your clients to never allow it" in
their hardening guidelines. That's really not ideal.
That said, having such an option would certainly be better than not
having any reasonable way on the client side to make sure that the
user's password isn't being sent to the server.
(I guess Unix-socket connections would be an exception, since we never
encrypt those.)
For the middle-ground "I don't care if the server sees my password, but
don't want someone on the network seeing it" it would seem unix sockets
would be alright.
BTW, do we have a client-side setting to insist that passwords not be
sent in MD5 hashing either? A person who is paranoid about this would
likely want to disable that code path as well.
No, but it would surely be good if we did... or we could just rip out
the md5 support entirely.
(Yes, I appreciate that the position I'm taking here isn't likely to be
popular and I'm not going to completely say no to compromises, but every
kind of compromise like these invites users to end up doing the insecure
thing; the more difficult we make it to do the insecure thing the better
overall for security.)
Thanks,
Stephen
Greetings,
* Magnus Hagander (magnus@hagander.net) wrote:
On Mon, Dec 21, 2020 at 7:44 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
BTW, do we have a client-side setting to insist that passwords not be
sent in MD5 hashing either? A person who is paranoid about this would
likely want to disable that code path as well.I don't think we do, and we possibly should. You can require channel
binding which will require scram which solves the problem, but it does
so only for scram.IIRC we've discussed having a parameter that says "allowed
authentication methods" on the client as well, but I don't believe it
has been built. But it wouldn't be bad to be able to for example force
the client to only attempt gssapi auth, regardless of what the server
asks for, and just fail if it's not there.
The client is able to require a GSS encrypted connection, and a savy
user will realize that they should 'kinit' (or equivilant) locally and
never provide their password explicitly to the psql (or equivilant)
command, but that's certainly less than ideal.
Having a way to explicitly tell libpq what auth methods are acceptable
was discussed previously and does generally seem like a good idea, as
otherwise there's a lot of risk of what are essentially downgrade
attacks.
Thanks,
Stephen
On Mon, Dec 21, 2020 at 8:06 PM Stephen Frost <sfrost@snowman.net> wrote:
Greetings,
* Magnus Hagander (magnus@hagander.net) wrote:
On Mon, Dec 21, 2020 at 7:44 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
BTW, do we have a client-side setting to insist that passwords not be
sent in MD5 hashing either? A person who is paranoid about this would
likely want to disable that code path as well.I don't think we do, and we possibly should. You can require channel
binding which will require scram which solves the problem, but it does
so only for scram.IIRC we've discussed having a parameter that says "allowed
authentication methods" on the client as well, but I don't believe it
has been built. But it wouldn't be bad to be able to for example force
the client to only attempt gssapi auth, regardless of what the server
asks for, and just fail if it's not there.The client is able to require a GSS encrypted connection, and a savy
user will realize that they should 'kinit' (or equivilant) locally and
never provide their password explicitly to the psql (or equivilant)
command, but that's certainly less than ideal.
Sure, but even if you do, then if you connect to a server that has gss
support but is configured for password auth, it will perform password
auth.
Having a way to explicitly tell libpq what auth methods are acceptable
was discussed previously and does generally seem like a good idea, as
otherwise there's a lot of risk of what are essentially downgrade
attacks.
That was my point exactly..
--
Magnus Hagander
Me: https://www.hagander.net/
Work: https://www.redpill-linpro.com/
Greetings,
* Magnus Hagander (magnus@hagander.net) wrote:
On Mon, Dec 21, 2020 at 8:06 PM Stephen Frost <sfrost@snowman.net> wrote:
* Magnus Hagander (magnus@hagander.net) wrote:
On Mon, Dec 21, 2020 at 7:44 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
BTW, do we have a client-side setting to insist that passwords not be
sent in MD5 hashing either? A person who is paranoid about this would
likely want to disable that code path as well.I don't think we do, and we possibly should. You can require channel
binding which will require scram which solves the problem, but it does
so only for scram.IIRC we've discussed having a parameter that says "allowed
authentication methods" on the client as well, but I don't believe it
has been built. But it wouldn't be bad to be able to for example force
the client to only attempt gssapi auth, regardless of what the server
asks for, and just fail if it's not there.The client is able to require a GSS encrypted connection, and a savy
user will realize that they should 'kinit' (or equivilant) locally and
never provide their password explicitly to the psql (or equivilant)
command, but that's certainly less than ideal.Sure, but even if you do, then if you connect to a server that has gss
support but is configured for password auth, it will perform password
auth.
Right, and that's bad. Think we agree on that. I was just saying that
someone who understanding how GSS works wouldn't actually provide their
password at that point. Trusting to that is definitely not sufficient
though.
Having a way to explicitly tell libpq what auth methods are acceptable
was discussed previously and does generally seem like a good idea, as
otherwise there's a lot of risk of what are essentially downgrade
attacks.That was my point exactly..
Yes, it was my intention to agree with you on this. :)
Thanks,
Stephen
On Mon, 2020-12-21 at 13:44 -0500, Tom Lane wrote:
Hm. I'm less concerned about that scenario than about somebody
snooping
the on-the-wire traffic. If we're going to invent a connection
setting
for this, I'd say that in addition to "ok to send cleartext password"
and "never ok to send cleartext password", there should be a setting
for
"send cleartext password only if connection is encrypted". Possibly
that should even be the default.
There was a fair amount of related discussion here:
/messages/by-id/227015d8417f2b4fef03f8966dbfa5cbcc4f44da.camel@j-davis.com
My feeling after all of that discussion is that the next step would be
to move to some kind of negotiation between client and server about
which methods are mutually acceptable. Right now, the protocol is
structured around the server driving the authentication process, and
the most the client can do is abort.
BTW, do we have a client-side setting to insist that passwords not be
sent in MD5 hashing either? A person who is paranoid about this
would
likely want to disable that code path as well.
channel_binding=require is one way to do it, but it also requires ssl.
Regards,
Jeff Davis
On Thu, Jun 03, 2021 at 11:02:56AM -0700, Jeff Davis wrote:
My feeling after all of that discussion is that the next step would be
to move to some kind of negotiation between client and server about
which methods are mutually acceptable. Right now, the protocol is
structured around the server driving the authentication process, and
the most the client can do is abort.
FWIW, this sounds very similar to what SASL solves when we try to
select a mechanism name, plus some filtering applied in the backend
with some HBA rule or some filtering in the frontend with a connection
parameter doing the restriction, like channel_binding here.
Introducing a new libpq parameter that allows the user to select which
authentication methods are allowed has been discussed in the past, I
remember vaguely writing/reviewing a patch doing that actually..
--
Michael