Bug 2479031 (CVE-2026-92821)
| Summary: | CVE-2026-92821 sssd: SSSD: Access control bypass via premature LDAP access rule evaluation | ||
|---|---|---|---|
| Product: | [Other] Security Response | Reporter: | OSIDB Bzimport <bzimport> |
| Component: | vulnerability | Assignee: | Product Security DevOps Team <prodsec-dev> |
| Status: | NEW --- | QA Contact: | |
| Severity: | medium | Docs Contact: | |
| Priority: | medium | ||
| Version: | unspecified | CC: | akhatavk, aos-team-art-private, asdas, dpaolell, jdelft, jupierce, lgarciaa, mbiarnes, ppalepu, ppostler, prdhamdh, rhel-process-autobot, security-response-team, sghai, sidsharm, suppawar, vlaad, watson-tool-maintainers |
| Target Milestone: | --- | Keywords: | Security |
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | --- | |
| Doc Text: |
A flaw was found in SSSD. When configured to evaluate password expiration warnings before restrictive access rules in LDAP (Lightweight Directory Access Protocol) environments, an expired-password warning terminates rule evaluation early and treats the access request as successful. A remote authenticated user with an expired password using an alternative authentication method, such as SSH public key authentication, can exploit this flaw to bypass access control restrictions and gain unauthorized access to protected systems.
|
Story Points: | --- |
| Clone Of: | Environment: | ||
| Last Closed: | Type: | --- | |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
| Bug Depends On: | 2546244 | ||
| Bug Blocks: | |||
AI_ONLY_REPORT package: sssd-2.12.0-1.el10 ------ Summary: LDAP Access Control Bypass When `pwd_expire_policy_warn` Precedes Restrictive Rules in `ldap_access_order`: an expired-password warning is converted into a successful PAM result before later LDAP access rules run, allowing configured `filter`, `host`, or similar restrictive checks to be bypassed. Requirements to exploit: A valid LDAP-backed account whose password is expired, an LDAP deployment using `access_provider = ldap` with a compatible password-expiration policy, `ldap_access_order` placing `pwd_expire_policy_warn` before restrictive rules, and a non-password authentication path such as SSH public key that still invokes SSSD account/access checks. Component affected: `sssd-2.12.0-1.el10`, LDAP access-control evaluation in `src/providers/ldap/sdap_access.c` (`sdap_access_check_next_rule()`) and success mapping in `src/providers/ldap/ldap_access.c` (`sdap_pam_access_handler_done()`). Version affected: `sssd-2.12.0-1.el10` in LDAP deployments where `ldap_access_order` places `pwd_expire_policy_warn` before restrictive rules. Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N - 6.8 (MEDIUM) AV:N - reachable over the network through services that rely on SSSD LDAP account/access checks, such as SSH. AC:H - exploitation depends on a specific non-default rule ordering, an expired-password state, and a compatible non-password authentication path. PR:L - the attacker needs a valid account that can authenticate to the target service. UI:N - no separate victim interaction is required once the attacker initiates authentication. S:U - the impact remains within the vulnerable service's own security scope. C:H - a successful bypass can expose data on systems or services that should have remained inaccessible under `filter`, `host`, or `rhost` restrictions. I:H - the same bypass can permit unauthorized actions within those protected systems or services. A:N - the flaw does not inherently reduce availability. Impact: Moderate. This is a real authorization bypass with meaningful confidentiality and integrity consequences where LDAP access rules are used as security boundaries, but exploitation requires a valid account, an expired-password condition, and a specific non-default `ldap_access_order` configuration. That fits a security flaw that can compromise resources under certain circumstances, while being less easily exploitable than a default-path or broadly reachable access-control failure. Embargo: no Reason: the issue is configuration-dependent, requires an already valid account, and can be mitigated immediately by reordering or removing `pwd_expire_policy_warn` from the front of `ldap_access_order`. Acknowledgement: Aisle Research Vulnerability Details: The documented purpose of `pwd_expire_policy_warn` is to warn while still allowing login. The issue here is narrower: in the LDAP access path, that warning state terminates ordered rule evaluation before later restrictive checks are reached. In `sdap_access_check_next_rule()`, rule processing only continues while `ret == EOK`; when `LDAP_ACCESS_EXPIRE_POLICY_WARN` converts an expired password into `ERR_PASSWORD_EXPIRED_WARN`, the loop stops and returns that non-`EOK` status. ```c while (ret == EOK) { ... case LDAP_ACCESS_EXPIRE_POLICY_WARN: ret = perform_pwexpire_policy(state, state->domain, state->pd, state->access_ctx->type, state->access_ctx->id_ctx->opts); if (ret == ERR_PASSWORD_EXPIRED) { ret = ERR_PASSWORD_EXPIRED_WARN; } break; ... } state->current_rule++; } return ret; ``` That returned status is then treated as success in `sdap_pam_access_handler_done()`, which maps both `EOK` and `ERR_PASSWORD_EXPIRED_WARN` to `PAM_SUCCESS`. In deployments using an ordered configuration such as `pwd_expire_policy_warn,filter,host`, later `filter`, `host`, or `rhost` checks are skipped entirely, so an expired-password user can be accepted by the warning path before the restrictive rules run. Steps to reproduce: 1. Configure an LDAP-backed SSSD domain with `access_provider = ldap`, `ldap_pwd_policy = shadow` (or `mit_kerberos`), `ldap_access_order = pwd_expire_policy_warn,filter,host`, and a restrictive `ldap_access_filter` or host rule that should deny the test user. 2. Ensure the test user's password is marked expired in the LDAP attributes used by the selected password policy. 3. Authenticate through a non-password method that still invokes account/access checks, such as SSH public key login. 4. Expected result: a later `filter` or `host` rule denies access. Actual result: the warning path returns `ERR_PASSWORD_EXPIRED_WARN`, the handler maps it to `PAM_SUCCESS`, and the later restrictive rules are not evaluated. Mitigation: Until a fix is available, do not place `pwd_expire_policy_warn` before restrictive entries in `ldap_access_order`. If warning behavior is still required, place it after `filter`, `host`, `rhost`, or other denial-capable rules, or use `pwd_expire_policy_reject` where expired accounts should not continue through the access chain. Proposed Fix: Record the warning state, continue evaluating the remaining ordered rules, and only return `ERR_PASSWORD_EXPIRED_WARN` after all configured access rules have passed. ```diff diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c — a/src/providers/ldap/sdap_access.c +++ b/src/providers/ldap/sdap_access.c @@ struct sdap_access_req_ctx { @@ size_t current_rule; enum sdap_access_control_type ac_type; + bool pw_expire_warn_seen; }; @@ state->conn = conn; state->current_rule = 0; + state->pw_expire_warn_seen = false; @@ static errno_t sdap_access_check_next_rule(struct sdap_access_req_ctx *state, case LDAP_ACCESS_EMPTY: /* we are done with no errors */ return EOK; + /* all rules passed; preserve warn semantics if seen */ + return state->pw_expire_warn_seen ? ERR_PASSWORD_EXPIRED_WARN : EOK; @@ case LDAP_ACCESS_EXPIRE_POLICY_WARN: ret = perform_pwexpire_policy(state, state->domain, state->pd, state->access_ctx->type, state->access_ctx->id_ctx->opts); if (ret == ERR_PASSWORD_EXPIRED) { ret = ERR_PASSWORD_EXPIRED_WARN; + state->pw_expire_warn_seen = true; + ret = EOK; } break; ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use