Предотвращение инъекции LDAP
Я работаю над своим первым настольным приложением, которое запрашивает LDAP. Я работаю в C под Unix и использую opends, и я новичок в LDAP. После некоторого разговора я заметил, что пользователь может изменить запрос LDAP, введя вредоносный код.
Я хотел бы знать, какие методы санировки известны не только для разработки C/unix, но и в более общих терминах, то есть в веб-разработке и т.д.
Я думал, что побег равных и точек с запятой будет достаточно, но не уверен.
Вот небольшой фрагмент кода, поэтому я могу уточнить вопрос:
String ldapSearchQuery = "(cn=" + $userName + ")";
System.out.println(ldapSearchQuery);
Очевидно, мне нужно дезинфицировать $userName, как указано в СТАТЬЯ OWASP
Ответы
Ответ 1
OWASP - хорошее руководство по безопасности, которое я использую много, и имеет пример кода (на Java, но вы должны иметь возможность перевести): http://www.owasp.org/index.php/Preventing_LDAP_Injection_in_Java
Кроме того, здесь ссылка на Active Directory: http://www.rlmueller.net/CharactersEscaped.htm
Ответ 2
Вы уже получили свой ответ в вопросительном комментарии. RFC 2254 имеет его.
Вот что я использую в PHP. Что-то эквивалентное на вашем языке должно быть достаточно.
/**
* Sanitizes ldap search strings.
* See rfc2254
* @link http://www.faqs.org/rfcs/rfc2254.html
* @since 1.5.1 and 1.4.5
* @param string $string
* @return string sanitized string
* @author Squirrelmail Team
*/
function ldapspecialchars($string) {
$sanitized=array('\\' => '\5c',
'*' => '\2a',
'(' => '\28',
')' => '\29',
"\x00" => '\00');
return str_replace(array_keys($sanitized),array_values($sanitized),$string);
}
Ответ 3
И это мой перевод С# функций escape в блоге, упомянутом @TrueBlood.
/// <summary>
/// Escape a string for usage in an LDAP DN to prevent LDAP injection attacks.
/// There are certain characters that are considered special characters in a DN.
/// The exhaustive list is the following: ',','\','#','+','<','>',';','"','=', and leading or trailing spaces
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static string EscapeForDN(string name)
{
StringBuilder sb = new StringBuilder();
if (name.Length > 0 && ((name[0] == ' ') || (name[0] == '#')))
{
sb.Append('\\'); // add the leading backslash if needed
}
for (int i = 0; i < name.Length; i++)
{
char curChar = name[i];
switch (curChar)
{
case '\\':
sb.Append(@"\\");
break;
case ',':
sb.Append(@"\,");
break;
case '+':
sb.Append(@"\+");
break;
case '"':
sb.Append("\\\"");
break;
case '<':
sb.Append(@"\<");
break;
case '>':
sb.Append(@"\>");
break;
case ';':
sb.Append(@"\;");
break;
default:
sb.Append(curChar);
break;
}
}
if (name.Length > 1 && name[name.Length - 1] == ' ')
{
sb.Insert(sb.Length - 1, '\\'); // add the trailing backslash if needed
}
return sb.ToString();
}
/// <summary>
/// Escape a string for usage in an LDAP DN to prevent LDAP injection attacks.
/// </summary>
public static string EscapeForSearchFilter(string filter)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < filter.Length; i++)
{
char curChar = filter[i];
switch (curChar)
{
case '\\':
sb.Append("\\5c");
break;
case '*':
sb.Append("\\2a");
break;
case '(':
sb.Append("\\28");
break;
case ')':
sb.Append("\\29");
break;
case '\u0000':
sb.Append("\\00");
break;
default:
sb.Append(curChar);
break;
}
}
return sb.ToString();
}