See how openedx compares to other vendors in security performance
Open edX Platform enables the authoring and delivery of online learning at any scale. The syncproviderdata endpoint in SAMLProviderDataViewSet allows authenticated Enterprise Admin users to supply an arbitrary URL via the metadataurl POST parameter. This URL is passed directly to requests.get() in fetchmetadataxml() without any URL validation, IP filtering, or scheme enforcement. An attacker with Enterprise Admin privileges can force the server to make HTTP requests to internal network services, cloud metadata endpoints (e.g., AWS 169.254.169.254), or other attacker-controlled destinations. This vulnerability is fixed by commit 6fda1f120ff5a590d120ae1180185525f399c6d0 and 70a56246dd9c9df57c596e64bdd8a11b1d9da054.
This openedx-translations repository contains translation files from Open edX repositories to be kept in sync with Transifex. Before moving to pulling translations from the openedx-translations repository via openedx-atlas, translations in the edx-platform repository were validated using edx-i18n-tools. This validation included protection against malformed translations and translations-based script injections. Prior to this patch, the validation implemented in the openedx-translations repository did not include the same protections. The maintainer inspected the translations in the edx-platform directory of both the main and open-release/redwood.master branches of the openedx-translations repository and found no evidence of exploited translation strings.
Summary
The syncproviderdata endpoint in SAMLProviderDataViewSet fetches SAML metadata from a URL stored in SAMLProviderConfig.metadatasource. 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 syncproviderdata. The fetch in fetchmetadataxml() 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 fetchsamlmetadata Celery task) was applied in GHSA-328g-7h4g-r2m9.
Details
Vulnerable code path:
enterprise/api/v1/views/samlutils.py: python def fetchmetadataxml(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.raiseforstatus()
enterprise/api/v1/views/samlproviderdata.py: python @action(detail=False, methods=['post'], urlpath='syncproviderdata') def syncproviderdata(self, request): ... metadataurl = samlprovider.metadatasource # set via SAMLProviderConfig PATCH xml = fetchmetadataxml(metadataurl) # 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: bash curl -X PATCH 'https://<instance>/auth/saml/v0/providerconfig/<pk>/' \ -H 'Authorization: Bearer <JWT>' \ -H 'Content-Type: application/json' \ -d '{"metadatasource": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'
Step 2: Trigger the server-side fetch: bash curl -X POST 'https://<instance>/auth/saml/v0/providerdata/syncproviderdata' \ -H 'Authorization: Bearer <JWT>' \ -H 'Content-Type: application/json' \ -d '{"enterprisecustomeruuid": "<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 validatesamlmetadataurl() (importable from common.djangoapps.thirdpartyauth.utils as of the openedx-platform fix in GHSA-328g-7h4g-r2m9) in fetchmetadataxml() 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.
Impact XSS Vulnerability in multiple XBlock Fields. Any platform that has deployed the XBlock will be impacted.
Patches https://github.com/openedx/xblock-drag-and-drop-v2/commit/53c4482f9bb6d8c7ccdf5253bd82c84a222b2492
The fix is compatible with all Open edX releases newer than Lilac.
Workarounds None.
References https://github.com/openedx/xblock-drag-and-drop-v2/pull/295#issuecomment-1277693864
Open edX Platform enables the authoring and delivery of online learning at any scale. The viewsurvey endpoint accepts a redirecturl GET parameter that is passed directly to HttpResponseRedirect() without any URL validation. When a non-existent survey name is provided, the server issues an immediate HTTP 302 redirect to the attacker-controlled URL. Additionally, the same unvalidated URL is embedded in a hidden form field and returned in a JSON response after form submission, where client-side JavaScript performs location.href = url. This enables phishing and credential theft attacks against authenticated Open edX users. This vulnerability is fixed with commit 76462f1e5fa9b37d2621ad7ad19514b403908970.
Open edX Platform enables the authoring and delivery of online learning at any scale. The HTML sanitizer cleanthreadhtmlbody() used for discussion notification emails fails to remove <style> tags from user-generated discussion post content. This content is rendered with Django's |safe template filter in email notification templates, allowing any enrolled student to inject arbitrary CSS into email notifications sent to other users. This enables email tracking (IP address disclosure), content spoofing, and phishing attacks. This vulnerability is fixed with commit cddc25cd791bb78f76833896e4778f668861df12.
Problem TL;DR: Any LTI tool that is integrated with on the Open edX platform can post a grade back for any LTI XBlock so long as it knows or can guess the block location for that XBlock.
In LTI 1.3, LTI tools can "pass back" scores that learners earn while using LTI tools to the edX platform. The edX platform then stores those LTI scores in a separate table. If the right conditions are met, these scores are then persisted to the LMS grades tables.
LTI tools can create what are called "line items" on the edX platform. A line item can be thought of as a column in a grade book; it stores results for a specific activity (i.e. XBlock) for a specific set of users (i.e. users in the course using the XBlock). A line item has an optional resourcelinkid field, which is basically the XBlock location. An LTI tool can supply any value for this field.
An LTI tool submits scores to the edX platform for line items. The code that uploads that score to the LMS grade tables determines which XBlock to upload the grades for by reading the resourcelinkid field of the associated line item. Because the LTI tool could have submitted any value for the resourcelinkid field, this introduces the potential for a nefarious LTI tool to submit scores for any LTI XBlock on the platform.
Impact Any LTI tool that is integrated with on the Open edX platform can post a grade back for any LTI XBlock so long as it knows the resourcelinkid (i.e. block location) for that XBlock.
The impact is a loss of integrity for LTI XBlock grades.
Patches No available patch
Workarounds No