CVE-2026-104040: Sssd: sssd: information disclosure via odata injection in entra id lookups
A flaw was found in SSSD. When configured with the Entra ID identity provider, input lookup names containing single quotes are not properly escaped before being included in Microsoft Graph Open Data Protocol (OData) queries. A low-privileged local user can exploit this flaw by submitting a crafted search request, altering query filters to broaden user or group searches. This can lead to information disclosure by retrieving unintended directory objects, as well as a Denial of Service (DoS) through excessive processing and cache population.
Other sources
AIONLYREPORT package: sssd-2.12.0-1.el10 ------ Summary: OData Injection in Entra ID Lookup via Unescaped Name Input (entraidlookup): crafted lookup names containing a single quote can alter Microsoft Graph OData $filter semantics, broadening Entra user or group queries and causing unintended directory objects to be fetched, processed, and cached. Requirements to exploit: A deployment of sssd-2.12.0-1.el10 using the IdP provider for Entra ID lookups, an IdP client that can read user or group data from Microsoft Graph, and a low-privileged actor who can trigger a name-based lookup through SSSD with crafted input that reaches entraidlookup(). Component affected: sssd-2.12.0-1.el10 IdP provider code in src/oidcchild/oidcchildid.c, entraidlookup(), with name-based input passed from src/providers/idp/idpid.c and returned objects processed by src/providers/idp/idpideval.c. Version affected: sssd-2.12.0-1.el10, when the IdP provider is used for Entra ID lookups, for example with idprovider = idp and idptype = entraid Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:L - 4.4 (MEDIUM) AV:L - The vulnerable path is reached through local SSSD account lookup activity rather than a directly remote network interface. AC:L - A single quote in the lookup name is sufficient to break OData string literal context. PR:L - A low-privileged local user who can trigger lookups is sufficient in affected deployments. UI:N - No separate victim interaction is required once the lookup is initiated. S:U - The impact remains within the SSSD and configured IdP lookup security scope. C:L - Successful injection can broaden directory reads beyond the intended lookup, subject to the configured Graph client's permissions. I:N - The available evidence shows no direct write or modification primitive. A:L - Broadened queries can return larger result sets, increasing processing and cache population work. Impact: Moderate. This issue can expose additional directory objects and create denial-of-service-like load in affected deployments, but it depends on the Entra ID IdP provider being configured and on the permissions already granted to the configured Graph client. The established outcome is limited to unintended read scope expansion and increased processing; there is no evidence of code execution, direct privilege escalation, or direct data modification. Under Red Hat's severity guidance, this is better characterized as a configuration-dependent confidentiality and availability issue with Moderate impact than an Important or Critical system compromise. Embargo: no Reason: The issue is configuration-dependent, has limited demonstrated impact, and can be addressed by a small escaping change, so public coordinated release with a fix is appropriate. Acknowledgement: Aisle Research Vulnerability Details: entraidlookup() builds OData $filter expressions by interpolating the externally influenced lookup name into single-quoted OData string literals and only URL-encoding the finished expression afterward. URL encoding at that stage does not escape OData string literal context, so a single quote in the name can terminate the literal and append additional operators or conditions. c if (sep == NULL || sep == input) { filter = tallocasprintf(restctx, "startsWith(userPrincipalName,'%s@')", input); } else { filter = tallocasprintf(restctx, "mail eq '%s' or userPrincipalName eq '%s'", input, input); } ... filterenc = urlencodestring(restctx, filter); Name-based lookups are forwarded into this path through the IdP provider's --name argument handling: c extraargs[c] = tallocasprintf(extraargs, "--name=%s", searchname != NULL ? searchname : filtervalue); The response handling path then iterates over every returned object and stores it without re-applying the original query intent after the Graph response is received: c jsonarrayforeach(data, index, obj) { ret = storefunc(idpidctx, obj, name); if (ret != EOK) { tmp = jsondumps(obj, 0); DEBUG(SSSDBGOPFAILURE, "Failed to store JSON %s [%s].\n", type, tmp); free(tmp); } } As a result, a crafted lookup name can broaden the filter used for Entra user or group searches, leading to over-fetching of directory data within the configured application's existing read permissions, additional processing, and cache pollution. The exact breadth of returned objects depends on the Graph permissions granted to the configured IdP client and on the specific lookup branch reached, but the available code paths support confidentiality and availability impact. The available evidence does not support direct integrity impact. Steps to reproduce: 1. Configure a test domain with idprovider = idp, idptype = entraid, and valid idpclientid, idpclientsecret, idptokenendpoint, and idpidscope values, using an application that can read users or groups from Microsoft Graph. 2. Trigger a name-based user or group lookup via NSS or another SSSD account lookup path that causes SSSD to pass the requested name into the Entra lookup path. 3. Use a crafted lookup name containing a single quote, for example a') or userPrincipalName ne ('. Depending on the exact lookup flow, a UPN-style variant of the payload may be needed when the name is propagated internally. 4. Enable verbose SSSD or libcurl debugging and inspect the outbound Graph request URL. 5. Observe that the generated $filter no longer represents only the intended exact or prefix lookup. For example, if the startsWith(userPrincipalName,'%s@') branch receives the payload above, the resulting filter becomes logically equivalent to startsWith(userPrincipalName,'a') or userPrincipalName ne ('@'). 6. Confirm that the returned array is accepted by the IdP evaluation path and that each returned object is processed and stored, demonstrating broadened read scope and added processing work. Mitigation: Until a fix is available, restrict untrusted users from triggering IdP-backed name lookups in deployments using the Entra ID provider path, and keep the configured Graph application permissions as narrow as possible. If operationally acceptable, reject or sanitize lookup names containing single quotes before they reach the Entra lookup path. Increased SSSD or libcurl debug logging can help identify unexpectedly broadened $filter requests during monitoring. Proposed Fix: Escape single quotes for OData string literal context before interpolating input or shortname into the filter, then continue URL-encoding the completed expression. diff diff --git a/src/oidcchild/oidcchildid.c b/src/oidcchild/oidcchildid.c — a/src/oidcchild/oidcchildid.c +++ b/src/oidcchild/oidcchildid.c @@ #include "oidcchild/oidcchildutil.h" #include "util/util.h" +static char odataescapequotes(TALLOCCTX memctx, const char in) +{ + const char p; + char out; + + if (in == NULL) return NULL; + out = tallocstrdup(memctx, ""); + if (out == NULL) return NULL; + + for (p = in; p != '\0'; p++) { + out = (p == '\'') ? tallocasprintfappend(out, "''") + : tallocasprintfappend(out, "%c", p); + if (out == NULL) return NULL; + } + return out; +} + errnot entraidlookup(...) { @@ char shortname; + char shortname; + char escapedinput; + char escapedshortname; @@ + escapedinput = odataescapequotes(restctx, input); + if (escapedinput == NULL) { + ret = ENOMEM; + goto done; + } @@
filter = tallocasprintf(restctx, "startsWith(userPrincipalName,'%s@')", input); + filter = tallocasprintf(restctx, "startsWith(userPrincipalName,'%s@')", escapedinput); @@
input, input); + escapedinput, escapedinput); @@
filter = tallocasprintf(restctx, "displayName eq '%s'", input); + filter = tallocasprintf(restctx, "displayName eq '%s'", escapedinput); @@
filter = tallocasprintf(restctx, "displayName eq '%s'", input); + filter = tallocasprintf(restctx, "displayName eq '%s'", escapedinput); } else { + escapedshortname = odataescapequotes(restctx, shortname); + if (escapedshortname == NULL) { + ret = ENOMEM; + goto done; + } filter = tallocasprintf(restctx, "displayName eq '%s' or displayName eq '%s'",
input, shortname); + escapedinput, escapedshortname); }
------ This report was generated using AI technology. Always review AI-generated content prior to use
— Red Hat
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Compensating control
Until a fix is available, restrict untrusted users from triggering IdP-backed name lookups, or reject/sanitize lookup names containing single quotes before they reach the Entra ID lookup path.
- Compensating control
Keep the configured Graph application's permissions as narrow as possible, limited to the required user or group read access.
Event History
Frequently Asked Questions
Which deployments are exposed to this issue?
The issue applies to deployments of sssd-2.12.0-1.el10 configured to use the Entra ID identity provider for lookups. Exploitation also requires that the configured IdP client can read user or group data from Microsoft Graph.
What access does an attacker need?
An attacker needs low-privileged local access and must be able to trigger a name-based lookup through SSSD. The crafted lookup name must reach the entra_id_lookup path and contain a single quote.
What is the practical impact of exploitation?
A crafted lookup can alter Microsoft Graph OData filter behavior, broadening user or group searches and retrieving unintended directory objects. The resulting data may be processed and cached, and excessive processing or cache population can cause a denial of service.