как защититься от инъекций LDAP - PullRequest
8 голосов
/ 18 августа 2010

Мы создаем приложение, которое использует LDAP через php, и я подумал, есть ли что-нибудь, что вы можете сделать с внедрением в LDAP, и еще лучше, как защитить себя от инъекций LDAP?

Ответы [ 5 ]

9 голосов
/ 19 августа 2010

При создании фильтров LDAP необходимо убедиться, что значения фильтров обрабатываются в соответствии с RFC2254 :

Любые управляющие символы с ACII код <32, а также символы с особым значением в фильтрах LDAP "*", "(", ")" и "\" (обратный слеш) превращаются в представление обратной косой черты, за которой следуют два гекса цифры, представляющие шестнадцатеричное значение символа. </p>

Zend_Ldap например использует следующую подпрограмму

//[...]
$val = str_replace(array('\\', '*', '(', ')'), array('\5c', '\2a', '\28', '\29'), $val);
for ($i = 0; $i<strlen($val); $i++) {
    $char = substr($val, $i, 1);
    if (ord($char)<32) {
        $hex = dechex(ord($char));
        if (strlen($hex) == 1) $hex = '0' . $hex;
        $val = str_replace($char, '\\' . $hex, $val);
    }
}
//[...]
2 голосов
/ 30 июня 2016

В PHP 5.6+ вы должны использовать функцию ldap_escape для значений фильтра и RDN. Такие как:

// Escaping an LDAP filter for ldap_search ...
$username = ldap_escape($username, null, LDAP_ESCAPE_FILTER);
$filter = "(sAMAccountName=$username)";

// Escaping a DN to be used in an ldap_add, or a rename...
$rdn = ldap_escape('Smith, John', null, LDAP_ESCAPE_DN);
$dn = "cn=$rdn,dc=example,dc=local";

Кроме того, если вы принимаете пользовательский ввод для имен атрибутов при поиске, вы должны проверить, что это приемлемый OID или имя атрибута. Вы можете сделать это с помощью такой функции:

/**
 * Validate an attribute is an OID or a valid string attribute name.
 *
 * @param string
 * @return bool
 */
function isValidAttributeFormat($value)
{
    $matchOid = '/^[0-9]+(\.[0-9]+?)*?$/';
    $matchDescriptor = '/^\pL([\pL\pN-]+)?$/iu';

    return preg_match($matchOid, $value) 
        || preg_match($matchDescriptor, $value);
}

$attribute = 'sAMAccountName';
$value = 'foo';

if (!isValidAttributeFormat($attribute)) {
    throw new \InvalidArgumentException(sprintf('Invalid attribute name: %s', $attribute));
}

$value = ldap_escape($value, null, LDAP_ESCAPE_FILTER);
$filter = "($attribute=$value)";
2 голосов
/ 18 августа 2010

Следует учитывать, что привязка LDAP с именем пользователя (DN), но ни один пароль не считается анонимной привязкой.Поэтому, если вам нужно проверить, могут ли переданные учетные данные связываться через LDAP для проверки пользователя, если они передают пустой пароль, и вы передали его как есть, вы можете пропустить кого-то неправильно.

1 голос
/ 18 августа 2010

В большинстве случаев для LDAP используется учетная запись только для чтения. Поскольку LDAP плохо записывает, обновления происходят только в очень маленьких разделах приложения, где может использоваться другая учетная запись.

Даже тогда язык запросов и язык обновлений полностью разделены.

Для защиты от отображения нежелательной информации обрабатывайте все вводимые пользователем данные как испорченные и следите за тем, чтобы испорченные данные никогда не использовались перед анализом, очисткой и надлежащим образом экранированием и копированием в чистую переменную.

Точно так же вы можете рассмотреть только выбор данных, которые вы ожидаете от ответа, и вернуть их для отображения.

0 голосов
/ 30 июня 2016
function ldap_quote($str) {
    return str_replace(
            array( '\\', ' ', '*', '(', ')' ),
            array( '\\5c', '\\20', '\\2a', '\\28', '\\29' ),
            $str
    );
}
...