CVE-2026-53635 Overview
CVE-2026-53635 is a missing authorization vulnerability [CWE-862] in the Open edX Platform, an open-source system for authoring and delivering online learning at scale. The flaw resides in the set_course_mode_price() view function at lms/djangoapps/instructor/views/instructor_dashboard.py:430. The endpoint is decorated only with @login_required and performs no course-level permission check. Any authenticated user, including a learner with zero course roles, can send a single POST request to overwrite the honor mode price and currency of any course on the platform. The vulnerability has been patched via commit 59bb6d6.
Critical Impact
An authenticated low-privilege user can tamper with course pricing data across the entire platform, causing revenue loss, financial reporting inconsistencies, and disruption of enrollment workflows.
Affected Products
- Open edX Platform versions prior to commit 59bb6d6
- Open edX LMS instructor dashboard component (lms/djangoapps/instructor/views/instructor_dashboard.py)
- Deployments exposing the set_course_mode_price URL route
Discovery Timeline
- 2026-09-02 - CVE-2026-53635 published to the National Vulnerability Database (NVD)
- 2026-09-02 - Last updated in NVD database
Technical Details for CVE-2026-53635
Vulnerability Analysis
The set_course_mode_price() view function accepts POST requests to update the price and currency associated with a course's honor mode. The function relies solely on Django's @login_required decorator, which verifies session authentication but not authorization. The view does not call any course-level role check such as has_access or require_course_permission, meaning a learner account with no instructor or staff role can invoke the endpoint successfully.
Although the frontend modal that once used this endpoint was removed during a prior cleanup, the URL route and view remained live. This produced an orphan endpoint that is not visible in the current UI but is still routable and callable directly. Successful exploitation writes an entry into the CourseModesArchive table and overwrites the active price for the target course.
Root Cause
The root cause is a missing authorization check [CWE-862]. Authentication was conflated with authorization, allowing any logged-in user to reach a privileged pricing operation. The endpoint should have required Django staff or instructor role validation before mutating course mode state.
Attack Vector
Exploitation requires only network access, a valid authenticated session, and knowledge of the target course identifier. The attacker sends a single crafted POST request containing course_price and currency fields to the set_course_mode_price route. No user interaction is required from a victim.
"""
set the new course price and add new entry in the CourseModesArchive Table
"""
+ if not request.user.is_staff:
+ return JsonResponse(
+ {'message': _("You do not have permission to perform this action.")},
+ status=403
+ )
try:
course_price = int(request.POST['course_price'])
except ValueError:
Source: GitHub Commit 59bb6d6. The patch inserts an explicit request.user.is_staff check and returns HTTP 403 for non-staff callers before any pricing logic executes.
Detect Identity Attacks the Moment Authentication Fails
Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.
Stop Identity AttacksDetection Methods for CVE-2026-53635
Indicators of Compromise
- Unexpected POST requests to the set_course_mode_price URL from non-staff user accounts
- New rows in the CourseModesArchive table attributed to users without instructor or staff roles
- Course honor mode price or currency values changing outside of scheduled administrative workflows
- HTTP 200 responses to set_course_mode_price from user agents that do not match the instructor dashboard
Detection Strategies
- Review Django and web server access logs for requests to the set_course_mode_price route and correlate the requesting user's role with the response status
- Audit the CourseModesArchive table for entries whose changed_by field does not map to a course staff or platform staff account
- Compare pre- and post-change price snapshots against approved pricing records maintained by finance or program teams
Monitoring Recommendations
- Emit application-level audit events for every price mutation and forward them to a centralized logging or SIEM platform
- Alert on any 2xx response to the set_course_mode_price endpoint originating from a session lacking staff privileges
- Monitor for repeated POSTs to legacy or orphan LMS endpoints as an early signal of endpoint enumeration
How to Mitigate CVE-2026-53635
Immediate Actions Required
- Upgrade Open edX Platform to a build that includes commit 59bb6d6 or later
- Review the CourseModesArchive table for unauthorized price changes since deployment and roll back affected courses to approved values
- Rotate or invalidate sessions if unauthorized modifications are confirmed, and investigate the associated accounts
Patch Information
The fix is delivered in commit 59bb6d6, with related changes in commits f25bbc4 and fd93ef5. Additional details are available in the GitHub Security Advisory GHSA-rqq6-w4pv-7pjv. The patch adds a request.user.is_staff check that returns HTTP 403 for non-staff callers.
Workarounds
- Block the set_course_mode_price URL at the reverse proxy or web application firewall for all requests until the patch is deployed
- Remove or disable the URL route mapping for the orphan endpoint in the LMS urls configuration since the frontend modal has already been deleted
- Restrict access to the instructor dashboard subtree to authenticated staff-role sessions using ingress rules
# Example NGINX rule to block the orphan endpoint until patched
location ~* /courses/.+/instructor/api/set_course_mode_price {
return 403;
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

