CVE-2023-54409
Executive Summary
CVE-2023-54409 is a stored/reflected cross-site scripting (XSS) vulnerability in Frappe (the ERPNext web framework) affecting versions before 13.46.1 and 14.x before 14.20.0. The flaw resides in the html2text function, which insufficiently sanitizes user-supplied HTML before it is rendered. An authenticated attacker can submit crafted HTML that bypasses weak sanitization, resulting in JavaScript execution in the browser of any user who views the rendered content — enabling session hijacking, credential theft, and action forgery within the ERP context.
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
The vulnerability class is CWE-80 (Improper Neutralization of Script-Related HTML Tags in a Web Page), a specific variant of cross-site scripting. The affected component is the html2text function, which converts HTML input to plain text for downstream rendering or storage. The NVD description states that this function "weakly sanitizes user input," meaning the sanitization routine does not neutralize at least one class of script-bearing HTML. Rather than rejecting or encoding dangerous constructs, the weak filter permits crafted HTML to survive the transformation and reach a rendering context where the browser interprets it as executable markup.
The attack surface is any Frappe feature that ingests user-controlled HTML and passes it through html2text before display — common in rich-text fields, comments, descriptions, and web-form submissions. Because the attacker must be authenticated (PR:L) and must supply the malicious content, while a separate victim user must view that content (UI:R), the CVSS vector reflects a high attack complexity component and no availability or integrity impact as scored. Confidentiality impact is High, consistent with the ability to read page content, session tokens, or data accessible to the victim's authenticated session.
No function names, parameters, or endpoints beyond html2text are disclosed in the advisory; the sanitization bypass mechanism is not enumerated. No public proof-of-concept, Nuclei template, or exploit code was available at the time of analysis. The description does not specify whether the XSS is stored or reflected; the phrase "users who view the rendered content" is consistent with a stored (persistent) XSS, but this cannot be conclusively confirmed from the data provided.
The CVSS vector — AV:N (network-reachable), AC:H (attacker must overcome sanitization/context conditions), PR:L (authenticated), UI:R (victim interaction), S:U (scope unchanged), C:H/I:N/A:N — describes a targeted, low-privilege-persistence XSS that primarily threatens information confidentiality within a single security scope.
Exploitation Scenarios
No public PoC is available; the attack chain below is inferred at the vulnerability-class level from the NVD description. Specific implementation details beyond the html2text function are not disclosed and are therefore not fabricated here.
Reconnaissance / Target Identification. The attacker identifies a Frappe/ERPNext instance running a vulnerable version (before 13.46.1 or 14.x before 14.20.0). Publicly exposed Frappe deployments can be fingerprinted through HTTP response characteristics. The attacker requires an authenticated account on the target system (PR:L).
Trigger of the Flaw Class. The attacker locates a feature that accepts user-supplied HTML and routes it through
html2textbefore rendering. Becausehtml2textweakly sanitizes input, the attacker submits crafted HTML containing script-bearing constructs that the weak filter fails to neutralize. The vulnerability class (CWE-80) implies the filter does not properly handle script-related HTML tags or their attributes.Payload / Execution Method. Per the advisory, the crafted HTML is "insufficiently sanitized" and "execut[es] scripts in the browsers of users who view the rendered content." At the class level, the attacker embeds JavaScript (or an event-handler attribute) that survives sanitization; when a victim renders the page, the browser executes the script in the victim's authenticated session context.
Post-Exploitation Impact. Successful execution allows the attacker to act in the victim's browser session — reading page content, exfiltrating data visible to the victim, or performing state-changing actions within the ERP scope. The CVSS score reflects High confidentiality impact with no integrity or availability impact as scored, though session-based XSS in an ERP context can frequently be leveraged for broader actions. No threat actor campaign or in-the-wild exploitation is documented.
Impact Assessment
Frappe/ERPNext is a widely deployed open-source enterprise resource planning and low-code platform handling business-critical data (finance, HR, CRM). An authenticated XSS in this context is significant: the victim is typically a privileged business user, and script execution occurs with that user's session privileges.
- Confidentiality (C:H): The primary scored impact. Script can read rendered content and session-accessible data.
- Integrity (I:N) / Availability (A:N): No direct scored impact, though XSS in practice can enable action forgery.
- Blast radius: Limited to users who view attacker-controlled rendered content; Scope is Unchanged (S:U), so the injection stays within the Frappe application's security authority.
- Attack complexity: High (AC:H) and requires authenticated attacker (PR:L) plus victim interaction (UI:R), moderating overall severity. Base score 4.8 (Medium).
- Enterprise impact includes potential credential/session compromise, data disclosure of ERP records, and lateral phishing within the platform, but no server-side compromise or RCE is implied.
Detection Guidance
Sigma Rule
title: Frappe html2text XSS Attempt via Crafted HTML Input
id: 4f9c1e2a-7b3d-4a5e-9c1f-0d2e6a8b3c44
status: experimental
description: Detects submission of script-bearing HTML to Frappe that may bypass weak html2text sanitization (CVE-2023-54409).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2023-54409
author: Threat Intelligence
date: 2024/01/01
logsource:
product: web
service: frappe
detection:
selection_method:
http.method: 'POST'
selection_payload:
http.request.body|contains:
- '<script'
- 'onerror='
- 'onload='
- 'javascript:'
- '<svg'
- 'onmouseover='
condition: selection_method and selection_payload
fields:
- c-ip
- cs-uri-stem
- http.request.body
falsepositives:
- Legitimate rich-text content containing escaped or encoded markup
level: medium
tags:
- attack.t1059.007
- cve.2023.54409
YARA Rule
rule CVE_2023_54409_Frappe_html2text_XSS
{
meta:
description = "Detects script-bearing HTML payloads targeting Frappe html2text XSS (CVE-2023-54409)"
author = "Threat Intelligence"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2023-54409"
date = "2024-01-01"
severity = "medium"
strings:
$tag1 = "<script" ascii nocase
$tag2 = "</script>" ascii nocase
$evt1 = "onerror=" ascii nocase
$evt2 = "onload=" ascii nocase
$evt3 = "onmouseover=" ascii nocase
$proto = "javascript:" ascii nocase
$svg = "<svg" ascii nocase
$frappe = "html2text" ascii nocase
condition:
uint16(0) == 0x3C3F or filesize > 0 and
(2 of ($tag*) or 1 of ($evt*) or $proto or $svg) and $frappe
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2023-54409 Frappe html2text XSS Attempt - script tag in HTTP body"; flow:established,to_server; http.method; content:"POST"; http.request_body; content:"<script"; nocase; http.request_body; content:"html2text"; nocase; reference:cve,2023-54409; classtype:web-application-attack; sid:2023544090; rev:1;)
Elastic Detection
sequence by source.ip with maxspan=5s
[ network where network.protocol == "http" and http.request.method == "POST" ]
[ network where network.protocol == "http" and http.request.body contains "<script" ]
Splunk SPL Query
index=web sourcetype=access_combined OR sourcetype=frappe
| eval body = coalesce(http_request_body, form_data, "")
| where match(body, "(?i)(<script|onerror=|onload=|onmouseover=|javascript:)") AND (match(body, "(?i)html2text") OR match(uri_path, "(?i)frappe|api|web_form"))
| stats count min(_time) as first_seen max(_time) as last_seen by src_ip, uri_path, http_user_agent
| convert ctime(first_seen) ctime(last_seen)
| sort - count
Wazuh OSSEC Rule
<group name="web,frappe,xss,">
<rule id="100409" level="10">
<decoded_as>json</decoded_as>
<field name="http.method">POST</field>
<match_type>pcre2</match_type>
<field name="http.request.body">(?i)(<script|onerror=|onload=|onmouseover=|javascript:)</field>
<description>CVE-2023-54409: Possible Frappe html2text XSS payload detected in POST body</description>
<mitre>
<id>T1059.007</id>
</mitre>
<group>cve_2023_54409,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source). The NVD description references fixed versions (13.46.1 and 14.20.0), but no vendor advisory, commit, or patch source was confirmed in the tracked data.
1) Immediate mitigations
- Restrict who can create or edit rich-text content that is rendered to other users; apply least privilege to content-authoring roles.
- Enable a Content Security Policy (CSP) with
script-src 'self'and disallow inline script execution to reduce XSS impact. - Deploy WAF rules that block script-bearing HTML (
<script, event-handler attributes,javascript:URIs) in submitted content, as reflected in the detection rules above. - Disable or limit rich-text/HTML input in fields that are displayed to other users until upgrade is validated.
2) Patch / upgrade steps
- Upgrade Frappe to 13.46.1 (13.x branch) or 14.20.0 or later (14.x branch).
- Verify the fix by re-testing the
html2textrendering path with benign HTML probes. - Back up the site and database before upgrading; test in a staging environment.
3) Long-term hardening
- Replace weak ad-hoc HTML sanitization with a maintained, spec-compliant sanitizer library; treat all user HTML as untrusted.
- Adopt output encoding appropriate to the rendering context and enforce CSP across the platform.
- Add regression tests for the
html2textsanitization path to prevent reintroduction. - Establish a routine upgrade cadence for Frappe and monitor vendor advisories.
References
- NVD: https://nvd.nist.gov/vuln/detail/CVE-2023-54409
- CWE-80: https://cwe.mitre.org/data/definitions/80.html
- Frappe/ERPNext project: https://frappeframework.com
- MITRE ATT&CK T1059.007 (JavaScript): https://attack.mitre.org/techniques/T1059/007/
- CISA KEV: Not applicable — CVE-2023-54409 is not listed in the CISA Known Exploited Vulnerabilities catalog, and no exploit-in-the-wild or threat actor campaign is documented in the available data.
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.