Miggo Logo

CVE-2025-62366: Mailgen has HTML Injection and XSS Filter Bypass in Plaintext Emails

N/A

CVSS Score

Basic Information

EPSS Score
-
Published
10/14/2025
Updated
10/14/2025
KEV Status
No
Technology
TechnologyJavaScript

Technical Details

CVSS Vector
-
Package NameEcosystemVulnerable VersionsFirst Patched Version
mailgennpm<= 2.0.302.0.31

Vulnerability Intelligence
Miggo AIMiggo AI

Miggo AIRoot Cause Analysis

The analysis of the vulnerability and the provided patch (commit 7279a983481d05c51aa451e86146f98aaa42fee9) points directly to a logical flaw in the Mailgen.prototype.generatePlaintext function located in index.js. The core of the vulnerability is the incorrect order of sanitization operations. The function first stripped what it thought were all HTML tags and then decoded HTML entities. This allowed malicious, entity-encoded HTML to pass through the stripping filter, only to be decoded afterward, effectively re-injecting the HTML into the output. The patch corrects this by reversing the order: it first decodes all HTML entities, ensuring any hidden HTML is revealed, and then it strips all HTML tags. Therefore, Mailgen.generatePlaintext is the single, clearly identifiable vulnerable function that would be active during the exploitation of this vulnerability.

Vulnerable functions

Mailgen.generatePlaintext
index.js
The function was vulnerable because it attempted to strip HTML tags *before* decoding HTML entities. An attacker could provide HTML-encoded tags (e.g., `&lt;img src=x onerror=alert(1)&gt;`). These encoded tags would not be matched by the HTML stripping regex. Subsequently, the `he.decode()` function would convert these entities back into raw HTML, which would then be present in the final output, leading to an HTML injection and potential Cross-Site Scripting (XSS) vulnerability when the plaintext email is rendered in a client that interprets HTML.

WAF Protection Rules

WAF Rule

### Summ*ry *n *TML inj**tion vuln*r**ility in pl*int*xt *m*ils **n*r*t** *y M*il**n **s ***n *is*ov*r**. Your proj**t is *****t** i* you us* t** `M*il**n.**n*r*t*Pl*int*xt(*m*il)` m*t*o* *n* p*ss in us*r-**n*r*t** *ont*nt. T** issu* w*s *is*ov*r**

Reasoning

T** *n*lysis o* t** vuln*r**ility *n* t** provi*** p*t** (*ommit ****************************************) points *ir**tly to * lo*i**l *l*w in t** `M*il**n.prototyp*.**n*r*t*Pl*int*xt` *un*tion lo**t** in `in**x.js`. T** *or* o* t** vuln*r**ility is