Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-72911

CVE-2026-72911: ERPNext Template Injection RCE Vulnerability

CVE-2026-72911 is a template injection remote code execution vulnerability in ERPNext that allows authenticated users to execute arbitrary code. This article covers technical details, affected versions, impact, and mitigation.

Published:

CVE-2026-72911 Overview

CVE-2026-72911 is a server-side template injection vulnerability in ERPNext, the open source Enterprise Resource Planning platform built on the Frappe framework. The flaw resides in erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py, where validate_template and render_template calls process the subject, body, and pdf_name fields with unrestricted Jinja globals, including frappe.utils. Any authenticated user holding a common operational role can inject template expressions, execute arbitrary server-side Python code, and read data across the application. The issue is resolved in ERPNext versions 15.118.0 and 16.29.0.

Critical Impact

Authenticated users with low-privilege operational roles can achieve remote code execution and cross-tenant data access on the ERPNext application server.

Affected Products

  • ERPNext versions prior to 15.118.0 (15.x branch)
  • ERPNext versions prior to 16.29.0 (16.x branch)
  • Deployments exposing the Process Statement of Accounts DocType to operational roles

Discovery Timeline

  • 2026-08-10 - CVE-2026-72911 published to NVD
  • 2026-08-13 - Last updated in NVD database

Technical Details for CVE-2026-72911

Vulnerability Analysis

The defect is a server-side template injection classified under [CWE-1336: Improper Neutralization of Special Elements Used in a Template Engine]. ERPNext's Process Statement of Accounts feature accepts user-supplied Jinja templates in the subject, body, and pdf_name fields. These templates are validated and rendered with a full Jinja environment that exposes the frappe.utils namespace and other unrestricted globals.

Because the rendering context is not sandboxed, attackers can craft template expressions that call into Python builtins reachable through Jinja object traversal. Successful injection yields code execution in the ERPNext application worker, cross-doctype data reads, and access to any secrets available to the Frappe process. The scope changes from the vulnerable component to the entire application, which is why the impact extends beyond the requesting user's role boundary.

Root Cause

The root cause is calling validate_template() without the restrict_globals=True flag. Without that flag, the Frappe template validator permits the full library of Jinja globals, allowing constructs such as attribute chaining through frappe.utils to reach dangerous callables. Authorization to open the Process Statement of Accounts document is granted to common operational roles, so the vulnerability is reachable without administrator privileges.

Attack Vector

An authenticated attacker opens or edits a Process Statement of Accounts record, places a malicious Jinja expression in subject, body, or pdf_name, and triggers the send or preview workflow. The server evaluates the template and executes the embedded payload under the identity of the ERPNext worker process. The attack is network-reachable and requires only low-privileged credentials.

python
# Patch: restrict Jinja globals in Process Statement of Accounts templates
if not self.pdf_name:
    self.pdf_name = "{{ customer.customer_name }}"

-validate_template(self.subject)
-validate_template(self.body)
-validate_template(self.pdf_name)
+validate_template(self.subject, restrict_globals=True)
+validate_template(self.body, restrict_globals=True)
+validate_template(self.pdf_name, restrict_globals=True)

if not self.customers:
    frappe.throw(_("Customers not selected."))
# Source: https://github.com/frappe/erpnext/commit/5f6952b15c1f6ee893770d5bc618558a6ba41a28

Detection Methods for CVE-2026-72911

Indicators of Compromise

  • Process Statement of Accounts records whose subject, body, or pdf_name fields contain Jinja constructs referencing frappe.utils, __class__, __mro__, __subclasses__, os, or subprocess.
  • Unexpected child processes spawned by the Frappe or Gunicorn worker, such as sh, bash, python, or curl invocations.
  • Outbound network connections from the ERPNext application host to unfamiliar destinations shortly after statement-of-accounts activity.
  • Frappe error logs showing Jinja rendering exceptions tied to the process_statement_of_accounts DocType.

Detection Strategies

  • Audit the ERPNext database table tabProcess Statement Of Accounts for template fields containing suspicious Jinja tokens or Python dunder attributes.
  • Enable process-execution telemetry on ERPNext hosts and alert on shell or interpreter processes descended from the Frappe worker.
  • Correlate Frappe audit logs of Process Statement of Accounts submissions with subsequent file system, credential, or database access anomalies.

Monitoring Recommendations

  • Ingest Frappe application logs, web server access logs, and host process telemetry into a centralized analytics platform to enable cross-source correlation.
  • Baseline normal statement-of-accounts submission volume per user and alert on deviations, especially from accounts with only operational roles.
  • Monitor egress traffic from ERPNext servers and flag connections to non-approved destinations following template rendering events.

How to Mitigate CVE-2026-72911

Immediate Actions Required

  • Upgrade ERPNext to version 15.118.0 or 16.29.0, which apply restrict_globals=True to the Process Statement of Accounts template validators.
  • Inventory user accounts holding roles that can access the Process Statement of Accounts DocType and revoke unnecessary assignments.
  • Review existing Process Statement of Accounts records and remove any template content that references Python internals or frappe.utils callables.
  • Rotate secrets, API keys, and service credentials accessible to the Frappe worker if evidence of exploitation is found.

Patch Information

The fix is delivered in ERPNext v15.118.0 and v16.29.0. The change adds the restrict_globals=True parameter to the validate_template calls in process_statement_of_accounts.py, as shown in commits 5f6952b, 88443e4, and ecb6d48. Full details are published in GitHub Security Advisory GHSA-qq49-v74j-hjh7 and Pull Request #56458.

Workarounds

  • If patching cannot occur immediately, restrict the Process Statement of Accounts DocType to administrators via Frappe role permissions.
  • Disable the Process Statement of Accounts scheduling and email workflows until the upgrade is applied.
  • Deploy a network policy that blocks outbound connections from the ERPNext worker except to required dependencies, limiting exploitation impact.
bash
# Upgrade ERPNext using the bench CLI
bench get-app --branch version-15 erpnext
bench update --reset
bench --site all migrate

# Verify installed version meets the fixed release
bench version | grep -i erpnext

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.