mirror of
https://github.com/asterisk/asterisk.git
synced 2026-07-01 04:29:38 -07:00
res_config_ldap: Escape LDAP filter values per RFC 4515
The LDAP realtime driver constructs search filters by directly concatenating user-supplied values without RFC 4515 escaping. When LDAP is used as a realtime backend for endpoint identification, characters with special meaning in LDAP filters (*, (, ), \) can be injected via the SIP From header username. Add ldap_filter_escape_value() that escapes RFC 4515 special characters to their \HH hex representation, and apply it to non-LIKE query values. The LIKE query path preserves the existing wildcard conversion behavior with a note for maintainers. Resolves: #GHSA-r6c2-hwc2-j4mp
This commit is contained in:
committed by
George Joseph
parent
8f51e97808
commit
56deaaa063
+52
-3
@@ -733,6 +733,40 @@ static int replace_string_in_string(char *string, const char *search, const char
|
||||
return replaced;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Escape a value for safe inclusion in an LDAP filter per RFC 4515.
|
||||
*
|
||||
* Characters that have special meaning in LDAP filters are escaped
|
||||
* to their \\HH hex representation: * ( ) \\ and NUL.
|
||||
*
|
||||
* \param value The raw value to escape
|
||||
* \param escaped Output buffer (caller-allocated ast_str)
|
||||
*/
|
||||
static void ldap_filter_escape_value(const char *value, struct ast_str **escaped)
|
||||
{
|
||||
ast_str_reset(*escaped);
|
||||
for (; *value; value++) {
|
||||
switch (*value) {
|
||||
case '*':
|
||||
ast_str_append(escaped, 0, "\\2a");
|
||||
break;
|
||||
case '(':
|
||||
ast_str_append(escaped, 0, "\\28");
|
||||
break;
|
||||
case ')':
|
||||
ast_str_append(escaped, 0, "\\29");
|
||||
break;
|
||||
case '\\':
|
||||
ast_str_append(escaped, 0, "\\5c");
|
||||
break;
|
||||
default:
|
||||
ast_str_append(escaped, 0, "%c", *value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Append a name=value filter string. The filter string can grow.
|
||||
*/
|
||||
static void append_var_and_value_to_filter(struct ast_str **filter,
|
||||
@@ -742,9 +776,15 @@ static void append_var_and_value_to_filter(struct ast_str **filter,
|
||||
char *new_name = NULL;
|
||||
char *new_value = NULL;
|
||||
const char *like_pos = strstr(name, " LIKE");
|
||||
struct ast_str *escaped_value;
|
||||
|
||||
ast_debug(2, "name='%s' value='%s'\n", name, value);
|
||||
|
||||
escaped_value = ast_str_create(256);
|
||||
if (!escaped_value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (like_pos) {
|
||||
int len = like_pos - name;
|
||||
|
||||
@@ -753,11 +793,20 @@ static void append_var_and_value_to_filter(struct ast_str **filter,
|
||||
value = new_value = ast_strdupa(value);
|
||||
replace_string_in_string(new_value, "\\_", "_");
|
||||
replace_string_in_string(new_value, "%", "*");
|
||||
name = convert_attribute_name_to_ldap(table_config, name);
|
||||
/* Note: The LIKE path preserves original wildcard behavior.
|
||||
* A more comprehensive escaping of the LIKE path is left
|
||||
* to the maintainers familiar with the query semantics.
|
||||
*/
|
||||
ast_str_append(filter, 0, "(%s=%s)", name, value);
|
||||
} else {
|
||||
name = convert_attribute_name_to_ldap(table_config, name);
|
||||
ldap_filter_escape_value(value, &escaped_value);
|
||||
ast_str_append(filter, 0, "(%s=%s)", name,
|
||||
ast_str_buffer(escaped_value));
|
||||
}
|
||||
|
||||
name = convert_attribute_name_to_ldap(table_config, name);
|
||||
|
||||
ast_str_append(filter, 0, "(%s=%s)", name, value);
|
||||
ast_free(escaped_value);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
Reference in New Issue
Block a user