CVE-2026-66000 Overview
CVE-2026-66000 is an authorization flaw in Frappe, a full-stack web application framework. The Document Follow notification generator does not re-evaluate a recipient's current document permissions before sending scheduled emails. Users whose access was revoked or reduced continue to receive document data by email. The issue affects versions prior to 16.23.0 and 15.112.0, and is categorized under [CWE-863: Incorrect Authorization].
Critical Impact
Users with revoked or downgraded permissions continue to receive follow-up email notifications containing document content, resulting in unauthorized information disclosure.
Affected Products
- Frappe framework versions prior to 15.112.0
- Frappe framework versions prior to 16.23.0
- Applications built on Frappe that use the Document Follow feature
Discovery Timeline
- 2026-08-07 - CVE-2026-66000 published to NVD
- 2026-08-07 - Last updated in NVD database
Technical Details for CVE-2026-66000
Vulnerability Analysis
Frappe's Document Follow feature lets users subscribe to documents and receive periodic email digests summarizing changes. The scheduled job that assembles these digests iterates over stored Document Follow records and constructs message content per user. Before the patch, the loop did not verify whether the recipient still held read permission on the referenced document.
Because permissions are stored separately from follow subscriptions, revoking a user's access to a doctype or specific record did not automatically clear existing follows. The digest job continued to render document content and email it to the previously subscribed user. This produces a persistent information disclosure channel that outlives active authorization.
The flaw is a business logic and authorization failure rather than an injection or memory-safety issue. Exploitation is passive: an attacker who once held access simply waits for scheduled digests to continue arriving after access removal.
Root Cause
The function assembling digest content in frappe/desk/form/document_follow.py iterated latest_document_follows and called get_message() without invoking frappe.has_permission() for the recipient. Authorization was implicitly assumed from the presence of a Document Follow record, violating the principle that permission must be checked at the time of data disclosure.
Attack Vector
The vector is network-adjacent and requires low privileges. An account that previously followed a document retains delivery of subsequent email digests after an administrator revokes its permissions. No active request or token is needed; the scheduled job continues delivering content until the follow record is manually purged.
# Patched code from frappe/desk/form/document_follow.py
valid_document_follows = []
for document_follow in latest_document_follows:
if not frappe.has_permission(
document_follow.ref_doctype, "read", doc=document_follow.ref_docname, user=user
):
frappe.db.delete(
"Document Follow",
{
"ref_doctype": document_follow.ref_doctype,
"ref_docname": document_follow.ref_docname,
"user": user,
},
)
continue
content = get_message(document_follow.ref_docname, document_follow.ref_doctype, frequency, user)
if content:
message = message + content
# Source: https://github.com/frappe/frappe/commit/0914acb998004b3878eb5cf57b765115305b49a6
The patch inserts a frappe.has_permission() check for read access before rendering content. When the check fails, the stale Document Follow record is deleted and the loop continues, preventing further leakage.
Detection Methods for CVE-2026-66000
Indicators of Compromise
- Outbound Document Follow digest emails delivered to user accounts whose role or permission records were modified in the audit log.
- Document Follow table entries referencing ref_doctype and ref_docname values for which the associated user no longer holds read permission.
- User reports of receiving update emails for records they can no longer open in the Frappe UI.
Detection Strategies
- Query the tabDocument Follow table and cross-reference each (user, ref_doctype, ref_docname) tuple against frappe.has_permission(); flag any tuple that fails the check.
- Audit outbound mail logs for the Document Follow digest template and compare recipients to the current permission matrix for the referenced doctype.
- Review the Frappe version reported by the /api/method/frappe.utils.change_log.get_versions endpoint against fixed versions 15.112.0 and 16.23.0.
Monitoring Recommendations
- Alert on permission-revocation events in Frappe followed by continued digest delivery to the same account within one scheduled interval.
- Track scheduled job runs for send_email_alert in the Document Follow module and log recipient counts to baseline deviations after role changes.
- Retain email gateway logs long enough to correlate access revocations with subsequent notification delivery.
How to Mitigate CVE-2026-66000
Immediate Actions Required
- Upgrade Frappe to version 15.112.0 or 16.23.0 or later, depending on the deployed major release.
- Purge stale Document Follow records for any user whose permissions have been revoked or reduced since the feature was enabled.
- Review audit logs for permission changes over the retention window and notify data owners of potential prior disclosure.
Patch Information
The fix is committed in 0914acb998004b3878eb5cf57b765115305b49a6 and b02c1aec2c75eb0819cc6730dd230c2acb0fa60d, and is released in Frappe 16.23.0 and 15.112.0. See the Frappe GitHub Security Advisory GHSA-wcm9-vvcc-r8pr for the full disclosure.
Workarounds
- Disable the Document Follow feature or the associated scheduled email job until the patched version can be deployed.
- Manually run a cleanup script that iterates Document Follow records and deletes entries where frappe.has_permission(ref_doctype, "read", doc=ref_docname, user=user) returns false.
- Restrict outbound Document Follow emails to recipient groups whose permissions are static and centrally managed.
# Upgrade Frappe using bench to a fixed version
bench switch-to-branch version-15 frappe --upgrade
bench update --patch
# or for the 16.x branch
bench switch-to-branch version-16 frappe --upgrade
bench update --patch
# Verify installed version meets or exceeds 15.112.0 or 16.23.0
bench version
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

