Skip to main content

Escapes the LDAP search filter to prevent LDAP injection attacks.

namespace Util
{
    using System.Text;

    /// <summary>
    /// LDAP utilities.
    /// </summary>
    public static class LdapUtil
    {
        #region - Escape Chars -

        private const char BackSlashChar = '\\';
        private const string BackSlashCharEscaped = "\\5c";

        private const char AsteriskChar = '*';
        private const string AsteriskCharEscaped = "\\2a";

        private const char LeftParenthesisChar = '(';
        private const string LeftParenthesisCharEscaped = "\\28";

        private const char RightParenthesisChar = ')';
        private const string RightParenthesisCharEscaped = "\\29";

        private const char NullUnicodeChar = '\u0000';
        private const string NullUnicodeCharEscaped = "\\00";

        private const char ForwardSlashChar = '/';
        private const string ForwardSlashCharEscaped = "\\2f";

        #endregion

        /// <summary>
        /// Escapes the LDAP search filter to prevent LDAP injection attacks.
        /// </summary>
        /// <param name="searchFilter">The search filter.</param>
        /// <returns>The escaped search filter.</returns>
        /// <remarks>
        ///     See: https://blogs.oracle.com/shankar/entry/what_is_ldap_injection
        ///     See: http://msdn.microsoft.com/en-us/library/aa746475.aspx
        /// </remarks>
        public static string EscapeSearchFilter(string searchFilter)
        {
            var escape = new StringBuilder();

            for (var i = 0; i < searchFilter.Length; ++i)
            {
                var current = searchFilter[i];

                switch (current)
                {
                    case BackSlashChar:
                        escape.Append(BackSlashCharEscaped);
                        break;
                    case AsteriskChar:
                        escape.Append(AsteriskCharEscaped);
                        break;
                    case LeftParenthesisChar:
                        escape.Append(LeftParenthesisCharEscaped);
                        break;
                    case RightParenthesisChar:
                        escape.Append(RightParenthesisCharEscaped);
                        break;
                    case NullUnicodeChar:
                        escape.Append(NullUnicodeCharEscaped);
                        break;
                    case ForwardSlashChar:
                        escape.Append(ForwardSlashCharEscaped);
                        break;
                    default:
                        escape.Append(current);
                        break;
                }
            }

            return escape.ToString();
        }
    }
}