CVE-2026-85271 Overview
CVE-2026-85271 is a stored cross-site scripting (XSS) vulnerability [CWE-79] in the Open edX Platform, the open-source learning management system that powers course authoring and delivery at scale. The flaw affects releases from Redwood through Ulmo and Verawood.1. The add_additional_attributes_to_notifications function in openedx/core/djangoapps/notifications/email/utils.py assigns discussion notification content without sanitizing values returned by get_notification_content. An enrolled student can inject CSS-capable markup into a discussion post_title, which digest and batched email templates render as trusted HTML.
Critical Impact
Authenticated learners can inject markup into digest emails to enable open-tracking pixels, content spoofing, and phishing against other learners on CSS-rendering mail clients.
Affected Products
- Open edX Platform releases from Redwood through Ulmo (prior to Ulmo.4)
- Open edX Platform Verawood prior to Verawood.1
- Deployments using digest or batched email notifications for discussion posts
Discovery Timeline
- 2026-09-18 - CVE-2026-85271 published to NVD
- 2026-09-24 - Last updated in NVD database
Technical Details for CVE-2026-85271
Vulnerability Analysis
The vulnerability resides in the notification email pipeline. The function add_additional_attributes_to_notifications in openedx/core/djangoapps/notifications/email/utils.py copies notification content assembled by get_notification_content in openedx/core/djangoapps/notifications/base_notification.py. That content includes the post_title value supplied through lms/djangoapps/discussion/rest_api/discussions_notifications.py. No HTML escaping is applied before the value is passed to the digest template openedx/core/djangoapps/notifications/templates/notifications/digest_content.html, which renders it as safe HTML. When another learner opens the digest in a CSS-rendering mail client, injected markup executes for tracking or spoofing purposes.
Root Cause
The notification content-assembly path fails to call Django's escape helper on user-controlled post_title input. Digest templates trust the assembled string and emit it without additional sanitization. The immediate-email path is unaffected because it strips title markup and renders a separately sanitized body.
Attack Vector
An enrolled student creates a discussion post whose title contains CSS-capable HTML markup. When the platform generates digest or batched notification emails referencing that post, the malicious markup is rendered inline. Recipients using mail clients that process HTML and CSS trigger email-open beacons or view spoofed content that can facilitate phishing.
# Patch: escape user input in notification content templates
"""
Base setup for Notification Apps and Types.
"""
+from django.utils.html import escape
from django.utils.translation import gettext_lazy as _
from .email_notifications import EmailCadence
Source: GitHub Commit 52f2b3b
Detection Methods for CVE-2026-85271
Indicators of Compromise
- Discussion posts with post_title values containing HTML tags, inline style attributes, or background:url() CSS references pointing to external hosts.
- Outbound requests from mail-render infrastructure or learner clients to unfamiliar domains referenced by digest email content.
- Digest email HTML source containing <img>, <style>, or <link> elements sourced from unexpected origins.
Detection Strategies
- Query the discussions database for post titles matching regex patterns that include angle brackets, javascript:, or CSS url( sequences.
- Inspect rendered digest email payloads in the outbound mail queue for markup that should have been escaped.
- Correlate learner accounts creating posts with suspicious titles against subsequent recipient click-through or beacon telemetry.
Monitoring Recommendations
- Log and alert on unusually long or markup-heavy post_title submissions to the discussion API endpoint.
- Monitor egress from mail-processing systems for connections to newly observed domains introduced via digest content.
- Track user reports of unexpected imagery or links appearing in course digest emails.
How to Mitigate CVE-2026-85271
Immediate Actions Required
- Upgrade Open edX Platform to release ulmo.4 or verawood.1, which apply the escaping fix.
- Audit recent discussion posts across active courses for post_title values containing HTML or CSS markup and quarantine offending posts.
- Notify learners and staff of the phishing risk in past digest emails and remind recipients not to trust links rendered in notifications.
Patch Information
The fix adds from django.utils.html import escape and applies escaping to user-supplied notification content in openedx/core/djangoapps/notifications/base_notification.py. See the GitHub Security Advisory GHSA-rv5w-f4r5-h77g, Ulmo.4 release, and Verawood.1 release for full details. Additional commits are available at 2af03d2 and 5eae6e5.
Workarounds
- Temporarily disable digest and batched email cadences for discussion notifications, leaving only the immediate-email path enabled, since it strips title markup.
- Configure the outbound mail gateway to strip inline style attributes and remote image references from notification emails until patching is complete.
- Restrict discussion posting privileges in high-risk courses while the patch is being deployed.
# Example: pin Open edX to a patched release via Tutor
tutor config save --set OPENEDX_COMMON_VERSION=release/verawood.1
tutor images build openedx
tutor local launch
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.