in src/Zyborg.PassCore.PasswordProvider.LDAP/LdapPasswordChangeProvider.cs [199:242]
private string CleaningUsername(string username)
{
var cleanUsername = username;
var index = cleanUsername.IndexOf("@", StringComparison.Ordinal);
if (index >= 0)
cleanUsername = cleanUsername.Substring(0, index);
// Must sanitize the username to eliminate the possibility of injection attacks:
// * https://docs.microsoft.com/en-us/windows/desktop/adschema/a-samaccountname
// * https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/bb726984(v=technet.10)
var invalidChars = "\"/\\[]:;|=,+*?<>\r\n\t".ToCharArray();
if (cleanUsername.IndexOfAny(invalidChars) >= 0)
{
throw new ApiErrorException("Username contains one or more invalid characters", ApiErrorCode.InvalidCredentials);
}
// LDAP filters require escaping of some special chars:
// * http://www.ldapexplorer.com/en/manual/109010000-ldap-filter-syntax.htm
var escape = "()&|=><!*/\\".ToCharArray();
var escapeIndex = cleanUsername.IndexOfAny(escape);
if (escapeIndex < 0)
return cleanUsername ?? string.Empty;
var buff = new StringBuilder();
var maxLen = cleanUsername.Length;
var copyFrom = 0;
while (escapeIndex >= 0)
{
buff.Append(cleanUsername.Substring(copyFrom, escapeIndex));
buff.Append(string.Format("\\{0:X}", (int)cleanUsername[escapeIndex]));
copyFrom = escapeIndex + 1;
escapeIndex = cleanUsername.IndexOfAny(escape, copyFrom);
}
if (copyFrom < maxLen)
buff.Append(cleanUsername.Substring(copyFrom));
cleanUsername = buff.ToString();
_logger.LogWarning("Had to clean username: [{0}] => [{1}]", username, cleanUsername);
return cleanUsername ?? string.Empty;
}