Discussion:
Why do "strict acceptor checking"?
(too old to reply)
Ken Hornstein
2024-10-08 00:23:28 UTC
Permalink
Twice this week I have helped other sites deal with issues related to
"strict acceptor checking" (the programs in question were sshd and
sudo). Both of these programs explicitly have code that constructs a
service name based on the value of gethostname() and thus will only
accept a service ticket for that name regardless of what's actually
in the keytab, and this fails in a number of complicated multihomed
networking situations (sudo does this for the service principal passed
to krb5_verify_init_creds()). At least in the case of sshd there is an
explicit knob to turn this off.

However, this has made me wonder: why do this at all? What is the
possible security gain here? It's not the default in the code; you have
to explicitly write code to enable this behavior. But I can't really
think of a case where NOT having strict acceptor checking is a security
problem; I could maybe squint and envision some kind of weird hosted
server setup where it might matter, but I'm not sure that is ever done
in the real world. I will admit it is entirely possible I am missing
something; if I am, I'd sure like to understand what I am missing.

--Ken
Roland C. Dowdeswell
2024-10-08 09:50:36 UTC
Permalink
Post by Ken Hornstein
However, this has made me wonder: why do this at all? What is the
possible security gain here? It's not the default in the code; you have
to explicitly write code to enable this behavior. But I can't really
think of a case where NOT having strict acceptor checking is a security
problem; I could maybe squint and envision some kind of weird hosted
server setup where it might matter, but I'm not sure that is ever done
in the real world. I will admit it is entirely possible I am missing
something; if I am, I'd sure like to understand what I am missing.
I have always operated under the theory that one should make sure that
the keytab accepts exactly the set of principals that are required.
This is something that is under the ultimate control of the system
administrator. When an application turns on strict acceptor checking,
they remove this configrability from the system administrator which I
think makes the system much less flexible.

--
Roland C. Dowdeswell https://Imrryr.ORG/
Ken Hornstein
2024-10-08 13:42:55 UTC
Permalink
Post by Roland C. Dowdeswell
Post by Ken Hornstein
However, this has made me wonder: why do this at all? What is the
possible security gain here? It's not the default in the code; you have
to explicitly write code to enable this behavior. But I can't really
think of a case where NOT having strict acceptor checking is a security
problem; I could maybe squint and envision some kind of weird hosted
server setup where it might matter, but I'm not sure that is ever done
in the real world. I will admit it is entirely possible I am missing
something; if I am, I'd sure like to understand what I am missing.
I have always operated under the theory that one should make sure that
the keytab accepts exactly the set of principals that are required.
This is something that is under the ultimate control of the system
administrator. When an application turns on strict acceptor checking,
they remove this configrability from the system administrator which I
think makes the system much less flexible.
I'm completely with you, but clearly plenty of application writers do not
agree with this sentiment! So I'm wondering what I am missing.

--Ken
Simo Sorce
2024-10-08 14:04:12 UTC
Permalink
Post by Ken Hornstein
Post by Roland C. Dowdeswell
Post by Ken Hornstein
However, this has made me wonder: why do this at all? What is the
possible security gain here? It's not the default in the code; you have
to explicitly write code to enable this behavior. But I can't really
think of a case where NOT having strict acceptor checking is a security
problem; I could maybe squint and envision some kind of weird hosted
server setup where it might matter, but I'm not sure that is ever done
in the real world. I will admit it is entirely possible I am missing
something; if I am, I'd sure like to understand what I am missing.
I have always operated under the theory that one should make sure that
the keytab accepts exactly the set of principals that are required.
This is something that is under the ultimate control of the system
administrator. When an application turns on strict acceptor checking,
they remove this configrability from the system administrator which I
think makes the system much less flexible.
I'm completely with you, but clearly plenty of application writers do not
agree with this sentiment! So I'm wondering what I am missing.
There *are* weird cases where the keytab needs to contain multiple keys
for different principals, but you want to use only one of them for
*accepting* connections.

These days you can easily have separate keytabs for "client" vs
"server" keys and programmatically specify which keytab you want via
gss_acquire_cred_from(), but it hasn't always been like that. In the
past in some cases your only option was to use a fixed specific file on
the filesystem not even env vars...

Granted I think 99% of the time it is the other way around, so it would
be nice if we could rewind to the past and make strict acceptor default
to false, but there have been "reasons" for this behavior, and changing
the default now would risk opening up unsuspecting admins to unexpected
failures.

Simo.
--
Simo Sorce
Distinguished Engineer
RHEL Crypto Team
Red Hat, Inc
Ken Hornstein
2024-10-08 16:05:29 UTC
Permalink
Post by Simo Sorce
Post by Ken Hornstein
I'm completely with you, but clearly plenty of application writers do not
agree with this sentiment! So I'm wondering what I am missing.
There *are* weird cases where the keytab needs to contain multiple keys
for different principals, but you want to use only one of them for
*accepting* connections.
These days you can easily have separate keytabs for "client" vs
"server" keys and programmatically specify which keytab you want via
gss_acquire_cred_from(), but it hasn't always been like that. In the
past in some cases your only option was to use a fixed specific file on
the filesystem not even env vars...
I'm certainly kind of a grizzled old Kerberos user at this point and
I'm willing to believe that these weird corner cases exist, but part of
me wonders out loud how this attitude got proliferated to so many
applications. Also, I guess I find it personally frustating that a
practice that has caused me a ton of pain over a few decades is justified
by what I would charitably classify as "vague hand-waving".

But, fine, let's talk about a specific example. In the case of sudo,
the local hostname is used to build a "host" principal and passed in as
the server argument to krb5_verify_init_creds(). If you pass in NULL
instead to the server argument, krb5_verify_init_creds() will try
every "host" principal in the local keytab until one succeeds. Given
this is just to verify a Kerberos password, I am trying to come up with
any kind of scenario where the default behavior of krb5_verify_init_creds()
would cause a security problem. If there IS no such scenario, I'm
going to try to submit a patch upstream to change this behavior.

--Ken
Jeffrey Hutzelman
2024-10-08 17:20:11 UTC
Permalink
Post by Ken Hornstein
Post by Simo Sorce
Post by Ken Hornstein
I'm completely with you, but clearly plenty of application writers do
not
Post by Simo Sorce
Post by Ken Hornstein
agree with this sentiment! So I'm wondering what I am missing.
There *are* weird cases where the keytab needs to contain multiple keys
for different principals, but you want to use only one of them for
*accepting* connections.
These days you can easily have separate keytabs for "client" vs
"server" keys and programmatically specify which keytab you want via
gss_acquire_cred_from(), but it hasn't always been like that. In the
past in some cases your only option was to use a fixed specific file on
the filesystem not even env vars...
I'm certainly kind of a grizzled old Kerberos user at this point and
I'm willing to believe that these weird corner cases exist, but part of
me wonders out loud how this attitude got proliferated to so many
applications.
Also, I guess I find it personally frustating that a
Post by Ken Hornstein
practice that has caused me a ton of pain over a few decades is justified
by what I would charitably classify as "vague hand-waving".
Me too. We've been recommending calling gss_accept_sec_context with
GSS_C_NO_CREDENTIAL for a long time, and almost no one does that. it's
very annoying.

RFC4752 recommends that SASL implementations use a credential acquired for
GSS_C_NO_NAME, which is usually equivalent. It also recommends verifying,
after accepting a context, that the service principal used is of the
expected type. This mitigates the potential issues if keys for another
application are in the same keytab.



But, fine, let's talk about a specific example. In the case of sudo,
Post by Ken Hornstein
the local hostname is used to build a "host" principal and passed in as
the server argument to krb5_verify_init_creds(). If you pass in NULL
instead to the server argument, krb5_verify_init_creds() will try
every "host" principal in the local keytab until one succeeds.
AFAIK, that's a relatively recent feature in the grand scheme of things.
So, software that validates passwords has a reasonably good excuse for
assuming that host/$hostname is a valid service principal to use for that
purpose and that its key will be readily available.

We have sudo configured to use PAM, and use Russ's pam_krb5, which handles
this (and has some features we use to support use of /root principals for
sudo).

Unfortunately, the Cyrus SASL library does not support non-strict mode.
That has unfortunate implications for LDAP, IMAP, and SMTP. We developed
and submitted a patch for that quite a number of years ago, but it doesn't
seem to have gone anywhere.



Given
Post by Ken Hornstein
this is just to verify a Kerberos password, I am trying to come up with
any kind of scenario where the default behavior of krb5_verify_init_creds()
would cause a security problem. If there IS no such scenario, I'm
going to try to submit a patch upstream to change this behavior.
well, the keytab could contain a copy of a key that is known to other
services or to some user. even a principal intended to be used only as a
client could be an issue, if an attacker knows the key and can print valid
tickets.

So, maybe an option rather than a change to a different non-configurable
behavior. If I remember right, the structure of sudo makes adding a new
option a little annoying but not actually difficult.

-- Jeff
Ken Hornstein
2024-10-09 00:33:39 UTC
Permalink
Post by Jeffrey Hutzelman
Post by Ken Hornstein
Also, I guess I find it personally frustating that a
practice that has caused me a ton of pain over a few decades is justified
by what I would charitably classify as "vague hand-waving".
Me too. We've been recommending calling gss_accept_sec_context with
GSS_C_NO_CREDENTIAL for a long time, and almost no one does that. it's
very annoying.
It's comforting to know that at least I'm not the only old, grizzled Kerberos
user that feels that way.
Post by Jeffrey Hutzelman
Post by Ken Hornstein
But, fine, let's talk about a specific example. In the case of sudo,
the local hostname is used to build a "host" principal and passed in as
the server argument to krb5_verify_init_creds(). If you pass in NULL
instead to the server argument, krb5_verify_init_creds() will try
every "host" principal in the local keytab until one succeeds.
AFAIK, that's a relatively recent feature in the grand scheme of things.
I am chuckling at the realization that "relatively recent" in Kerberos
now means "within the last 12 years" (looks like that code went in to
MIT Kerberos version 1.11). Now I feel even older. It seems like the
sudo Kerberos code has been unchanged for even longer. But even then,
the previous implementation of krb5_verify_init_creds() just did the
same thing that sudo did, so the code in sudo was at best redundant
even when it was written.
Post by Jeffrey Hutzelman
well, the keytab could contain a copy of a key that is known to other
services or to some user. even a principal intended to be used only as a
client could be an issue, if an attacker knows the key and can print valid
tickets.
I mean, sure, that's possible ... but that could be true for the host
key!

I know that newer versions of MIT Kerberos have the configuration file
entry "ignore_acceptor_hostname" (first appeared in 1.10) which does
resolve these issues, so it's not as big of a deal as it once was.

--Ken
Russ Allbery
2024-10-09 01:19:01 UTC
Permalink
Post by Ken Hornstein
Post by Jeffrey Hutzelman
Me too. We've been recommending calling gss_accept_sec_context with
GSS_C_NO_CREDENTIAL for a long time, and almost no one does that. it's
very annoying.
It's comforting to know that at least I'm not the only old, grizzled
Kerberos user that feels that way.
You definitely are not. I don't know how many times I've tried to explain
this to people.
--
Russ Allbery (***@eyrie.org) <https://www.eyrie.org/~eagle/>
Loading...