Bug 2490796 (CVE-2026-12726)

Summary: CVE-2026-12726 awx: automation-controller: awx: GitHub webhook second-order SSRF via unvalidated statuses_url exfiltrates PAT credential
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security <prodsec-ir-bot>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedCC: dschmidt, erezende, jlanda, kshier, simaishi, smcdonal, stcannon, teagle, yguenane
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in the AWX GitHub webhook integration. When processing GitHub pull_request webhooks, the controller stores the pull_request.statuses_url value from the webhook payload without validating that it points to a trusted GitHub API endpoint. If a job template is configured with a GitHub Personal Access Token as its webhook credential, the controller later POSTs that token to the stored callback URL when posting job status updates. An attacker who can submit a correctly signed forged webhook using the job template's webhook_key can redirect the callback to an attacker-controlled URL and exfiltrate the configured GitHub PAT.
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:

Description OSIDB Bzimport 2026-06-19 15:10:44 UTC
A flaw was found in the AWX GitHub webhook integration. When a GitHub pull_request webhook is received, GithubWebhookReceiver.get_event_status_api() in awx/api/views/webhooks.py returns pull_request.statuses_url from the request body without validation. The value is stored in job extra variables as awx_webhook_status_api and later used by WebhookMixin.update_webhook_status() in awx/main/models/mixins.py as the callback URL when posting job status updates.
If a job template is configured with webhook_service=github and a GitHub Personal Access Token credential as webhook_credential, the controller sends that token in the Authorization header when POSTing to the stored callback URL on job completion. Although the controller is designed to post commit status updates back to GitHub, it does not restrict the callback URL to trusted GitHub API endpoints.
An attacker who can submit a forged webhook request with a valid HMAC-SHA1 signature for the target job template's webhook_key can supply an attacker-controlled statuses_url and cause exfiltration of the configured GitHub PAT when the triggered job completes. Normal GitHub webhook deliveries do not allow arbitrary contributors to control statuses_url; exploitation requires knowledge of the per-template webhook shared secret or privileged access to retrieve it from the controller.
Upstream: https://github.com/ansible/awx
Affected files:
  - awx/api/views/webhooks.py (GithubWebhookReceiver.get_event_status_api)
  - awx/main/models/mixins.py (WebhookMixin.update_webhook_status)