防止LDAP注入

时间:2010-06-12 13:10:44

标签: security ldap sanitization

我正在研究第一个查询LDAP的桌面应用。我正在使用unix并使用opends在C中工作,而且我是LDAP的新手。在讨论了一段时间之后,我注意到用户可以通过注入恶意代码来改变LDAP查询 我想知道哪些消毒技术是已知的,不仅用于C / unix开发,还用于更一般的术语,即Web开发等。 我认为逃避平等和分号就足够了,但不确定。

这是一小段代码,所以我可以更清楚地说明问题:

 String ldapSearchQuery = "(cn=" + $userName + ")";
 System.out.println(ldapSearchQuery); 

显然我需要清理$ userName,如OWASP ARTICLE

中所述

4 个答案:

答案 0 :(得分:10)

OWASP是一个很好的安全指南,我经常使用,并有示例代码(在Java中,但你应该能够翻译):   http://www.owasp.org/index.php/Preventing_LDAP_Injection_in_Java

此外,这是一个Active Directory特定的参考:   http://www.rlmueller.net/CharactersEscaped.htm

答案 1 :(得分:3)

你已经在问题评论中得到了答案。 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);
}

答案 2 :(得分:2)

这是我在@TrueBlood提到的博客中转义函数的C#转换。

/// <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();
}

答案 3 :(得分:0)

如果您使用的是Spring,则有一个类LdapEncoderhttps://docs.spring.io/spring-ldap/docs/current/apidocs/org/springframework/ldap/support/LdapEncoder.html),提供了在过滤器和DN中编码值的方法。 实际上,此类至少存在于至少两个spring库中,即spring-ldap-core和spring-security-ldap。在后者中两次:)