HI!
What really strikes users is the lack of feedback in case a unique constraint or other constraint fails.
Let's look at error messages of slapo-unique first. I'm experimenting with a pretty simple patch for returning the effective uniqueness filter in the diagnosticMessage.
Example output with this patch (line wrapped):
$ ldapadd -f test.ldif adding new entry "uid=foo,ou=Users,dc=example,dc=com" ldap_add: Constraint violation (19) additional info: non-unique attributes found with (|(uid=foo)(uidNumber=20000))
Even this minimum information is already somewhat useful. Of course it would be even more nice to get the list of non-unique attribute values returned. (I vaguely remember some idea for a "What Failed?" response control.)
Now formerly one of the arguments against returning more information in the diagnosticMessage was that this would reveal content information to an attacker which is obtained by an internal search with a more privileged authz-ID.
Yes, that's right.
But this problem exists anyway because an attacker can probe values by adding entries with non-unique attributes and determine whether an attribute value exists or not by distinguishing the result code constraintViolation(19) vs. insufficientAccessRights(50). Even worse this even works in case the attacker does not have read access anywhere!
This leads to the question whether some sort of access control or limit check should be applied in unique_search().
What do you think?
Ciao, Michael.
On Wed, Nov 15, 2017 at 05:09:31PM +0100, Michael Ströder wrote:
HI!
What really strikes users is the lack of feedback in case a unique constraint or other constraint fails.
Let's look at error messages of slapo-unique first. I'm experimenting with a pretty simple patch for returning the effective uniqueness filter in the diagnosticMessage.
[...]
Now formerly one of the arguments against returning more information in the diagnosticMessage was that this would reveal content information to an attacker which is obtained by an internal search with a more privileged authz-ID.
Yes, that's right.
But this problem exists anyway because an attacker can probe values by adding entries with non-unique attributes and determine whether an attribute value exists or not by distinguishing the result code constraintViolation(19) vs. insufficientAccessRights(50). Even worse this even works in case the attacker does not have read access anywhere!
This leads to the question whether some sort of access control or limit check should be applied in unique_search().
Hi, we can't enforce uniqueness without an unconstrained search and the side channel in one form or another is unavoidable (we still have to detect the conflict and reject the request).
We could check the conflicting entries to see whether the existence of one can be exposed to the client and decide which error code is appropriate. This would help plug that side channel, but might be quite expensive if there are many offending entries and as such would provide a different one again (open to the same class of attackers that you highlighted).
Not sure that's worth it?
Ondřej Kuzník wrote:
On Wed, Nov 15, 2017 at 05:09:31PM +0100, Michael Ströder wrote:
HI!
What really strikes users is the lack of feedback in case a unique constraint or other constraint fails.
Let's look at error messages of slapo-unique first. I'm experimenting with a pretty simple patch for returning the effective uniqueness filter in the diagnosticMessage.
[...]
Now formerly one of the arguments against returning more information in the diagnosticMessage was that this would reveal content information to an attacker which is obtained by an internal search with a more privileged authz-ID.
Yes, that's right.
But this problem exists anyway because an attacker can probe values by adding entries with non-unique attributes and determine whether an attribute value exists or not by distinguishing the result code constraintViolation(19) vs. insufficientAccessRights(50). Even worse this even works in case the attacker does not have read access anywhere!
This leads to the question whether some sort of access control or limit check should be applied in unique_search().
we can't enforce uniqueness without an unconstrained search and the side channel in one form or another is unavoidable (we still have to detect the conflict and reject the request).
Yes. That was already very clear to me.
We could check the conflicting entries to see whether the existence of one can be exposed to the client and decide which error code is appropriate. This would help plug that side channel, but might be quite expensive if there are many offending entries and as such would provide a different one again (open to the same class of attackers that you highlighted).
Not sure that's worth it?
There are two different aspects here:
1. Providing useful diagnostic message to the user so he can change the failed input. At least return the attributes checked to unique. This has much higher priority for me and I have a very simple patch just returning the unique search filter in the diagnostic message as shown in my original posting.
So would OpenLDAP developers accept that patch? Up to now this feature request was always rejected with the side-channel argument.
2. Closing the side channel: slapo-unique could simply take another simple limit-like argument for restricting the search to a specific group and reject all other requests with INSUFFICENT_ACCESS.
Ciao, Michael.