Bug 2511903 (CVE-2026-71367)
| Summary: | CVE-2026-71367 awx: WebSocket broadcast groups leak cross-organization job metadata | ||
|---|---|---|---|
| Product: | [Other] Security Response | Reporter: | OSIDB Bzimport <bzimport> |
| Component: | vulnerability | Assignee: | Product Security <prodsec-ir-bot> |
| Status: | NEW --- | QA Contact: | |
| Severity: | medium | Docs Contact: | |
| Priority: | medium | ||
| Version: | unspecified | CC: | dschmidt, jlanda, kshier, rbobbitt, security-response-team, simaishi, stcannon, teagle, yguenane |
| Target Milestone: | --- | Keywords: | Security |
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | --- | |
| Doc Text: |
An incorrect authorization vulnerability was found in AWX's WebSocket consumer. The consumer_access() function only enforces access controls for object-level event groups (job_events, workflow_events, ad_hoc_command_events) but does not restrict subscriptions to global broadcast groups such as 'jobs-status_changed'. When an authenticated user subscribes to a global broadcast group, the server accepts the subscription without verifying that the user has permission to view the associated resources. In multi-organization deployments, this allows a low-privilege user in one organization to receive real-time job status metadata from all organizations, including job IDs, status transitions, timestamps, and infrastructure topology details such as instance group names, bypassing the organization isolation enforced by the REST API.
|
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: | |||
AWX WebSocket subscriptions skip RBAC checks for global broadcast groups. The consumer_access() function in awx/main/access.py maps only object-level event groups to access classes: class_map = { 'job_events': JobAccess, 'workflow_events': WorkflowJobAccess, 'ad_hoc_command_events': AdHocCommandAccess, } return class_map.get(group_name) When a client subscribes to a broadcast group such as 'jobs-status_changed', group_name is 'jobs', so consumer_access() returns None. The consumer in awx/main/consumers.py only runs user_can_see_object_id() when the access class is not None; otherwise it adds the user to the requested group unconditionally: access_cls = consumer_access(group_name) if access_cls is not None: if not await self.user_can_see_object_id(user_access, oid): continue new_groups.add(name) The job model emits global status updates to 'jobs-status_changed' including job IDs, status changes, timestamps, and instance_group_name. In multi-organization deployments, a low-privilege user from one organization can receive real-time status metadata for jobs in all organizations that are otherwise hidden by the REST API.