|
|
3280a9 |
From 316aeae09468d6fd3b35422b236751eb1b5c309e Mon Sep 17 00:00:00 2001
|
|
|
ef1f48 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
ef1f48 |
Date: Tue, 9 Feb 2021 14:02:59 -0500
|
|
|
3280a9 |
Subject: [PATCH 1/2] Issue 4609 - CVE - info disclosure when authenticating
|
|
|
ef1f48 |
|
|
|
ef1f48 |
Description: If you bind as a user that does not exist. Error 49 is returned
|
|
|
ef1f48 |
instead of error 32. As error 32 discloses that the entry does
|
|
|
ef1f48 |
not exist. When you bind as an entry that does not have userpassword
|
|
|
ef1f48 |
set then error 48 (inappropriate auth) is returned, but this
|
|
|
ef1f48 |
discloses that the entry does indeed exist. Instead we should
|
|
|
ef1f48 |
always return error 49, even if the password is not set in the
|
|
|
ef1f48 |
entry. This way we do not disclose to an attacker if the Bind
|
|
|
ef1f48 |
DN exists or not.
|
|
|
ef1f48 |
|
|
|
ef1f48 |
Relates: https://github.com/389ds/389-ds-base/issues/4609
|
|
|
ef1f48 |
|
|
|
ef1f48 |
Reviewed by: tbordaz(Thanks!)
|
|
|
ef1f48 |
---
|
|
|
3280a9 |
dirsrvtests/tests/suites/basic/basic_test.py | 39 +++++++++++++++++++-
|
|
|
ef1f48 |
ldap/servers/slapd/back-ldbm/ldbm_bind.c | 4 +-
|
|
|
3280a9 |
ldap/servers/slapd/dse.c | 7 +++-
|
|
|
3280a9 |
3 files changed, 45 insertions(+), 5 deletions(-)
|
|
|
ef1f48 |
|
|
|
ef1f48 |
diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py
|
|
|
3280a9 |
index fc9af46e4..e35f34721 100644
|
|
|
ef1f48 |
--- a/dirsrvtests/tests/suites/basic/basic_test.py
|
|
|
ef1f48 |
+++ b/dirsrvtests/tests/suites/basic/basic_test.py
|
|
|
3280a9 |
@@ -9,7 +9,7 @@
|
|
|
ef1f48 |
|
|
|
ef1f48 |
from subprocess import check_output, PIPE, run
|
|
|
ef1f48 |
from lib389 import DirSrv
|
|
|
ef1f48 |
-from lib389.idm.user import UserAccounts
|
|
|
ef1f48 |
+from lib389.idm.user import UserAccount, UserAccounts
|
|
|
ef1f48 |
import pytest
|
|
|
ef1f48 |
from lib389.tasks import *
|
|
|
ef1f48 |
from lib389.utils import *
|
|
|
3280a9 |
@@ -1094,6 +1094,43 @@ def test_bind_invalid_entry(topology_st):
|
|
|
3280a9 |
topology_st.standalone.simple_bind_s(DN_DM, PW_DM)
|
|
|
ef1f48 |
|
|
|
ef1f48 |
|
|
|
ef1f48 |
+def test_bind_entry_missing_passwd(topology_st):
|
|
|
ef1f48 |
+ """
|
|
|
ef1f48 |
+ :id: af209149-8fb8-48cb-93ea-3e82dd7119d2
|
|
|
ef1f48 |
+ :setup: Standalone Instance
|
|
|
ef1f48 |
+ :steps:
|
|
|
ef1f48 |
+ 1. Bind as database entry that does not have userpassword set
|
|
|
ef1f48 |
+ 2. Bind as database entry that does not exist
|
|
|
ef1f48 |
+ 1. Bind as cn=config entry that does not have userpassword set
|
|
|
ef1f48 |
+ 2. Bind as cn=config entry that does not exist
|
|
|
ef1f48 |
+ :expectedresults:
|
|
|
ef1f48 |
+ 1. Fails with error 49
|
|
|
ef1f48 |
+ 2. Fails with error 49
|
|
|
ef1f48 |
+ 3. Fails with error 49
|
|
|
ef1f48 |
+ 4. Fails with error 49
|
|
|
ef1f48 |
+ """
|
|
|
ef1f48 |
+ user = UserAccount(topology_st.standalone, DEFAULT_SUFFIX)
|
|
|
ef1f48 |
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
|
|
|
ef1f48 |
+ # Bind as the suffix root entry which does not have a userpassword
|
|
|
ef1f48 |
+ user.bind("some_password")
|
|
|
ef1f48 |
+
|
|
|
ef1f48 |
+ user = UserAccount(topology_st.standalone, "cn=not here," + DEFAULT_SUFFIX)
|
|
|
ef1f48 |
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
|
|
|
ef1f48 |
+ # Bind as the entry which does not exist
|
|
|
ef1f48 |
+ user.bind("some_password")
|
|
|
ef1f48 |
+
|
|
|
ef1f48 |
+ # Test cn=config since it has its own code path
|
|
|
ef1f48 |
+ user = UserAccount(topology_st.standalone, "cn=config")
|
|
|
ef1f48 |
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
|
|
|
ef1f48 |
+ # Bind as the config entry which does not have a userpassword
|
|
|
ef1f48 |
+ user.bind("some_password")
|
|
|
ef1f48 |
+
|
|
|
ef1f48 |
+ user = UserAccount(topology_st.standalone, "cn=does not exist,cn=config")
|
|
|
ef1f48 |
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
|
|
|
ef1f48 |
+ # Bind as an entry under cn=config that does not exist
|
|
|
ef1f48 |
+ user.bind("some_password")
|
|
|
ef1f48 |
+
|
|
|
ef1f48 |
+
|
|
|
ef1f48 |
@pytest.mark.bz1044135
|
|
|
ef1f48 |
@pytest.mark.ds47319
|
|
|
ef1f48 |
def test_connection_buffer_size(topology_st):
|
|
|
ef1f48 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_bind.c b/ldap/servers/slapd/back-ldbm/ldbm_bind.c
|
|
|
ef1f48 |
index fa450ecd5..38d115a32 100644
|
|
|
ef1f48 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_bind.c
|
|
|
ef1f48 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_bind.c
|
|
|
ef1f48 |
@@ -76,8 +76,8 @@ ldbm_back_bind(Slapi_PBlock *pb)
|
|
|
ef1f48 |
case LDAP_AUTH_SIMPLE: {
|
|
|
ef1f48 |
Slapi_Value cv;
|
|
|
ef1f48 |
if (slapi_entry_attr_find(e->ep_entry, "userpassword", &attr) != 0) {
|
|
|
ef1f48 |
- slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL,
|
|
|
ef1f48 |
- NULL, 0, NULL);
|
|
|
ef1f48 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not have userpassword set");
|
|
|
ef1f48 |
+ slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
|
|
|
ef1f48 |
CACHE_RETURN(&inst->inst_cache, &e);
|
|
|
ef1f48 |
rc = SLAPI_BIND_FAIL;
|
|
|
ef1f48 |
goto bail;
|
|
|
ef1f48 |
diff --git a/ldap/servers/slapd/dse.c b/ldap/servers/slapd/dse.c
|
|
|
3280a9 |
index 3c2de75fc..b04fafde6 100644
|
|
|
ef1f48 |
--- a/ldap/servers/slapd/dse.c
|
|
|
ef1f48 |
+++ b/ldap/servers/slapd/dse.c
|
|
|
3280a9 |
@@ -1446,7 +1446,8 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this
|
|
|
ef1f48 |
|
|
|
ef1f48 |
ec = dse_get_entry_copy(pdse, sdn, DSE_USE_LOCK);
|
|
|
ef1f48 |
if (ec == NULL) {
|
|
|
ef1f48 |
- slapi_send_ldap_result(pb, LDAP_NO_SUCH_OBJECT, NULL, NULL, 0, NULL);
|
|
|
ef1f48 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not exist");
|
|
|
ef1f48 |
+ slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
|
|
|
ef1f48 |
return (SLAPI_BIND_FAIL);
|
|
|
ef1f48 |
}
|
|
|
ef1f48 |
|
|
|
3280a9 |
@@ -1454,7 +1455,8 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this
|
|
|
ef1f48 |
case LDAP_AUTH_SIMPLE: {
|
|
|
ef1f48 |
Slapi_Value cv;
|
|
|
ef1f48 |
if (slapi_entry_attr_find(ec, "userpassword", &attr) != 0) {
|
|
|
ef1f48 |
- slapi_send_ldap_result(pb, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, 0, NULL);
|
|
|
ef1f48 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Entry does not have userpassword set");
|
|
|
ef1f48 |
+ slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
|
|
|
ef1f48 |
slapi_entry_free(ec);
|
|
|
ef1f48 |
return SLAPI_BIND_FAIL;
|
|
|
ef1f48 |
}
|
|
|
3280a9 |
@@ -1462,6 +1464,7 @@ dse_bind(Slapi_PBlock *pb) /* JCM There should only be one exit point from this
|
|
|
ef1f48 |
|
|
|
ef1f48 |
slapi_value_init_berval(&cv, cred);
|
|
|
ef1f48 |
if (slapi_pw_find_sv(bvals, &cv) != 0) {
|
|
|
ef1f48 |
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, "Invalid credentials");
|
|
|
ef1f48 |
slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL);
|
|
|
ef1f48 |
slapi_entry_free(ec);
|
|
|
ef1f48 |
value_done(&cv;;
|
|
|
ef1f48 |
--
|
|
|
ef1f48 |
2.26.2
|
|
|
ef1f48 |
|