CVE case study

CVE-2026-78868: Unauthenticated Stored XSS in django-crm IMAP Email Subject Headers

A remote, unauthenticated attacker can send an email whose Subject header carries HTML that django-crm imports over IMAP, stores with mark_safe, and later renders unescaped in the Django-admin message list, running attacker JavaScript in a staff or superuser session. No fixed version was available at disclosure; the maintainer closed the private report without remediation.

Weakness
CWE-79
Affected
All versions up to and including commit 508e4dfe (main branch, 2026-06-29); no fixed version released.
Remediation state
No fixed version at disclosure; the maintainer closed the private report
Advisory published
4 Sep 2026

Official vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H

Why it matters

django-crm is a customer relationship management application built on Django. One of its features imports incoming email over IMAP and surfaces those messages inside the Django admin interface that staff use. The flaw is in how the imported Subject header is handled: in crm/utils/restore_imap_emails.py (the _notify_user routine) and in common/utils/usermiddleware.py, the Subject text is wrapped with Django's mark_safe helper before being stored. mark_safe tells the template engine the string is already safe and must not be HTML-escaped, so any markup in the Subject is later rendered verbatim.

An attacker needs no account and no prior access. They send an ordinary email to a mailbox the CRM imports, including the literal marker the importer looks for and a Subject header that contains an HTML payload such as an image tag with an onerror handler. When a staff member or superuser next loads the admin message list, the payload is rendered as live markup and the attacker's JavaScript executes inside that privileged admin session. Because the code runs in the operator's browser under their session, it crosses the boundary from an anonymous external sender into an authenticated administrative context, which is why the submitted vector scores it 9.6 Critical: the changed scope and full confidentiality, integrity, and availability impact reflect script execution against a high-privilege user.

The issue was reported to the maintainer through GitHub private vulnerability reporting under advisory GHSA-fqgm-2x23-c4xm. The maintainer closed the report without remediation, so it was submitted to MITRE's CNA-LR, and at disclosure no fixed version had been released. The engineering lesson is direct: mark_safe should never be applied to attacker-controlled input such as an email header. Trusting external text as pre-sanitized HTML removes the auto-escaping that would otherwise neutralize it, so the value should be escaped on output and mark_safe reserved for strings the application itself constructs.

References

Further reading

Evidence connected to this article.

Back to article start