edx-enterprise has SSRF via SAML metadata URL in sync_provider_data endpoint
Date: 2026-05
Affected: pip/edx-enterprise
Attack vector: ssrf
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-42860
CWE: CWE-918
CVSS: 8.5 (CVSS:3.1/AV: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](https://github.com/openedx/openedx-platform/security/advisories/GHSA-328g-7h4g-r2m9). ## Details **Vulnerable code path:** `enterprise/api/v1/views/saml_utils.py`: ```python 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`: ```python @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


Mitigations:

Architectural layers (MAESTRO):