CVE case study
CVE-2026-78866: Insecure Direct Object Reference in django-crm Original Email Views Exposes Other Departments' Mail
django-crm resolves emails in its view-original-email and download-original-email views by a client-supplied integer id with no owner or department check, so any authenticated low-privilege staff user can enumerate ids and read other departments' confidential email bodies, headers, and attachments. No fixed version was available at disclosure; the maintainer closed the private report without remediation.
- Weakness
- CWE-639, CWE-862
- Affected
- django-crm, all versions up to and including the latest main branch (commit 508e4dfe, 2026-06-29)
- Remediation state
- No fixed version at disclosure; the maintainer disputed and closed the private report
- Advisory published
- 4 Sep 2026
Official vectorCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N
Why it matters
django-crm stores customer correspondence as CrmEmail records and offers two custom views for retrieving the original message: view-original-email and download-original-email, wired up in crm/urls.py and implemented in crm/views/view_original_email.py (get_ea_eml_uid) and crm/views/download_original_email.py. Both views look up the record with CrmEmail.objects.get(id=object_id), using the integer id straight from the URL. The only gate is the staff_member_required decorator, so nothing checks whether the requesting user owns the email or belongs to the department it was filed under. The view-original-email-uid form goes a step further and reads messages by IMAP uid from any configured mail account.
An authenticated staff user with the lowest level of access in any department can increment the id in either URL and receive another department's full email content, headers, and attachments, fetched live from the IMAP server. The trust boundary that is broken is the one between departments inside a single CRM installation: a user who should see only their own team's mail can read the whole organisation's. The submitted vector, CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N, scores it 7.1 (High); confidentiality impact is high because the exposed material is other departments' customer correspondence, including attachments.
The issue was reported through GitHub private vulnerability reporting as advisory GHSA-37r3-q4cw-f7gq. The maintainer disputed and closed the report without remediation, so it was submitted to MITRE, which assigned CVE-2026-78866. At disclosure no fixed version had been released; every version up to and including commit 508e4dfe on the main branch is affected. A runtime Django TestCase demonstrating the cross-department read is available on request. The engineering lesson is that a staff-only decorator is an authentication check, not an authorization check: any view that loads a record by primary key must scope the query to the caller's owner or department before returning data.