CVE-2026-109612
Executive Summary
CVE-2026-109612 is a stored cross-site scripting (XSS) vulnerability in Frappe ERPNext, affecting versions before 15.120.0 and 16.x before 16.33.0. A report view interpolates stored record names into HTML markup without escaping, allowing any authenticated user who can create records to persist a crafted record name that executes attacker-controlled JavaScript in the browser session of any user who later opens the affected report. With a CVSS base score of 7.3 (High), successful exploitation yields high confidentiality and integrity impact on behalf of the victim user within the ERPNext web application.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
ERPNext is an open-source ERP platform built on the Frappe framework. The vulnerability class is CWE-79 (Improper Neutralization of Input During Web Page Generation), specifically the stored (persistent) variant. Per the NVD description, the flaw resides in "a report view that interpolates stored record names into markup without escaping." This means the report rendering path constructs HTML output by concatenating or template-injecting a record's name field (as stored in the database) directly into the response markup, rather than HTML-encoding it first.
Key mechanics:
- Input vector: The record
namefield, which an authenticated user can influence when creating records. In Frappe/ERPNext, document identifiers are frequently user-supplied strings, making thenamefield a durable storage sink for attacker-controlled content. - Storage: The malicious value is written to the database, not reflected transiently. This makes the payload persistent and re-triggered on every subsequent render of the report.
- Execution sink: The report view output. Because the stored name is interpolated unescaped, a name containing HTML/script constructs is rendered as active markup in the victim's browser.
- Trigger condition: Any user who later opens the affected report within their authenticated session. No interaction with the attacker's record beyond viewing the report is required.
The CVSS vector AV:N indicates the attack is network-reachable; AC:L no special conditions; PR:L the attacker needs a low-privileged authenticated account with record-creation rights; UI:R a victim must open the report; S:U scope is unchanged; and C:H/I:H/A:N reflect that script execution occurs in the context of the victim's ERPNext session, permitting read of data the victim can see and actions the victim can perform, while availability is not directly impacted.
Note: The NVD description does not name the specific report view, the exact parameter, or the underlying function. No public PoC or patch commit is available, so the precise code path cannot be confirmed from source. The above is a class-level analysis consistent with the vendor description.
Exploitation Scenarios
The attack chain below is inferred from the vulnerability class (stored XSS via unescaped interpolation) and the facts in the NVD description. No public PoC exists; specific function names, endpoints, or field labels are not available and are therefore not fabricated here.
Reconnaissance / target identification. The attacker identifies an internet- or intranet-exposed ERPNext instance (version fingerprinting via login page, static assets, or
/api/method/behavior). The attacker requires a valid low-privileged authenticated account with the ability to create records.Payload placement. Using their authenticated session, the attacker creates a record whose
name(or name-bearing field) contains a crafted value. Because the report view later interpolates this stored name into markup without escaping, the value is stored verbatim and serves as the injection payload. At the vulnerability-class level, the payload is an HTML/script fragment (e.g., markup containing an event handler or script element) intended to execute when rendered.Triggering execution. The attacker induces a victim — ideally a higher-privileged user such as an ERP administrator or finance approver — to open the affected report view. The victim must be authenticated. When the report renders, the stored name is emitted unescaped, and the browser parses and executes the injected script in the origin of the ERPNext application.
Post-exploitation impact. The script runs with the victim's session privileges. Consequences include: exfiltration of data visible to the victim (records, reports, tokens embedded in page context), and performing authenticated actions on the victim's behalf against the ERPNext application (creating/updating records, generating documents, or reusing the session). Availability is unaffected per the CVSS vector, but confidentiality and integrity impacts are High.
The stored nature means the payload persists across sessions until the malicious record is removed or remediated, effectively a low-privilege-to-elevated stored XSS pivot inside the ERP.
Impact Assessment
- Confidentiality (High): Script execution in the victim's session can read and exfiltrate any data the victim is authorized to view — potentially sensitive business, financial, customer, or HR records within the ERP.
- Integrity (High): The attacker can act as the victim, modifying or creating records and performing workflow actions available to that user, including approval or data-manipulation workflows.
- Availability (None): No direct denial of service is described.
- Scope (Unchanged): Impact is confined to the ERPNext application's own security context; no privilege boundary crossing at the OS or browser level is described.
- Blast radius: Any ERPNext deployment on affected versions where authenticated users can create records and where a shared report is consumed by privileged users. ERP systems commonly aggregate HR, finance, and supply-chain data, amplifying confidentiality impact. The PR:L/UI:R combination means a single low-privileged account plus user view of a report is sufficient.
- Base score: 7.3 (High). No EPSS score is currently published, and the CVE is not in CISA KEV; no in-the-wild exploitation is confirmed.
Detection Guidance
Sigma Rule
title: Potential ERPNext Stored XSS Payload in Record Name Field
id: 9f1c4b7a-2e6d-4c8a-b3f1-7a2d5e9c0f11
status: experimental
description: Detects creation/update events where record name-like fields contain HTML/script constructs consistent with stored XSS targeting report views.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-109612
author: valtersit.com
date: 2026/01/01
logsource:
product: erpnext
service: application
detection:
selection_endpoint:
http.request.method:
- POST
- PUT
- PATCH
selection_payload:
body|contains:
- '<script'
- 'onerror='
- 'onload='
- 'javascript:'
- '<svg'
- '<img'
condition: selection_endpoint and selection_payload
falsepositives:
- Legitimate business names containing angle brackets (rare)
level: medium
YARA Rule
rule CVE_2026_109612_ERPNext_StoredXSS
{
meta:
description = "Detects stored XSS payloads targeting Frappe ERPNext report views (CVE-2026-109612)"
author = "valtersit.com"
date = "2026-01-01"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-109612"
severity = "high"
strings:
$s1 = "<script" nocase
$s2 = "javascript:" nocase
$s3 = "onerror=" nocase
$s4 = "onload=" nocase
$s5 = "<svg" nocase
$s6 = "document.cookie" nocase
$s7 = "fetch(" nocase
condition:
any of ($s1, $s2, $s3, $s4, $s5) and any of ($s6, $s7)
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-109612 ERPNext Stored XSS Payload in Record Name"; flow:established,to_server; http.method; content:"POST"; http.request_body; content:"<script"; nocase; http.request_body; content:"|3c|/script|3e|"; nocase; reference:cve,2026-109612; classtype:web-application-attack; sid:2026109612; rev:1;)
Elastic Detection
sequence by source.ip with maxspan=5m
[ network where http.request.method in ("POST","PUT","PATCH") ]
[ network where http.request.body.text contains ("<script") or http.request.body.text contains ("onerror=") or http.request.body.text contains ("javascript:") ]
Splunk SPL Query
index=web sourcetype=*erpnext* (http_method=POST OR http_method=PUT OR http_method=PATCH)
| eval body=lower(coalesce(request_body, form_data, ""))
| where match(body, "<script|javascript:|onerror=|onload=|<svg")
| stats count min(_time) as first_seen max(_time) as last_seen values(uri) as uris values(clientip) as src_ips by user
| sort - count
Wazuh OSSEC Rule
<group name="web,erpnext,cve-2026-109612,">
<rule id="109612" level="10">
<decoded_as>web|json</decoded_as>
<field name="url">\.|POST|PUT|PATCH</field>
<regex type="pcre2">(?i)(<script|javascript:|onerror=|onload=|<svg)</regex>
<description>CVE-2026-109612: Possible ERPNext stored XSS payload submitted via record creation</description>
<mitre>
<id>T1059.007</id>
</mitre>
<group>web_attack,xss,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source). The 15.120.0 / 16.33.0 versions named in the NVD description represent the anticipated fixed baseline, but no vendor advisory, commit, or release note has been confirmed.
Immediate mitigations
- Treat affected ERPNext instances as at-risk until upstream confirmation. If versions 15.120.0+ / 16.33.0+ are already available in your update channel, validate and test them in staging before production rollout.
- Restrict the ability to create records to the minimum set of trusted roles; audit roles with create privileges on report-sourced doctypes.
- Restrict network exposure of ERPNext administrative and reporting interfaces to trusted networks/VPN.
- Deploy the detection rules above (WAF, IDS, SIEM) to alert on unescaped HTML/script constructs in record-name submissions and report-view access patterns.
- If a WAF is in place, enable XSS rulesets and create a rule to reject requests whose body contains script constructs in name fields.
Patch / upgrade steps
- There is currently no confirmed vendor patch notice. Monitor the Frappe/ERPNext release channels and the official security advisories for the 15.120.0 and 16.33.0 releases.
- When a fix is published: back up the database and site config, stage the upgrade, verify report views render record names escaped, then promote to production.
- After remediation, search historical records for stored payloads (see detection queries) and sanitize or delete any records with malicious names.
Long-term hardening
- Ensure contextual output encoding is applied to all user-controlled values rendered into report/view markup (framework templates should default to escaping; verify custom report code does not bypass it).
- Adopt Content Security Policy (CSP) with strict
script-srcto reduce XSS impact. - Enforce least privilege on record creation; regularly review ERPNext roles and permissions.
- Integrate SAST/dependency scanning into CI to catch unescaped interpolation in custom reports, and keep ERPNext updated.
References
- NVD — CVE-2026-109612: https://nvd.nist.gov/vuln/detail/CVE-2026-109612
- CWE-79 Improper Neutralization of Input During Web Page Generation: https://cwe.mitre.org/data/definitions/79.html
- MITRE ATT&CK T1059.007 (JavaScript): https://attack.mitre.org/techniques/T1059/007/
- Frappe ERPNext project repository and release notes: https://github.com/frappe/erpnext
- CISA Known Exploited Vulnerabilities Catalog (CVE not listed as of this report): https://www.cisa.gov/known-exploited-vulnerabilities-catalog
No threat actor campaigns or exploit-in-the-wild evidence have been reported for CVE-2026-109612 at the time of writing. No public PoC, exploit code, or Nuclei template is available.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.