CVE-2026-92595: Nodemailer before 9.1.1 Security Sandbox Bypass via resolveContent
Nodemailer (npm package nodemailer) versions 9.1.0 and earlier do not honor the disableFileAccess and disableUrlAccess sandbox options when message content is resolved through the public plugin API MailMessage.resolveContent() using the documented legacy three-argument signature resolveContent(data, key, callback). Because shared.resolveContent() normalizes the missing options argument to an empty object, the message-level flags copied into mail.data by the MailMessage constructor are discarded, and resolveContentValue() skips both access-control checks, reaching nmfetch(url) or fs.createReadStream(path). As a result, plugin or application code that resolves untrusted message content (html, text, attachment path or href) via this API can be induced to read arbitrary local files or issue outbound HTTP(S) requests (server-side request forgery), bypassing the sandbox the application enabled. The internal paths used by transporter.sendMail() (resolveAll(), convertDataImages(), and the MIME streaming path) are not affected. Fixed in version 9.1.1.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
nodemailerto a version that resolves this vulnerability.Fixed in 9.1.1 - Compensating control
Avoid using the public plugin API `MailMessage.resolveContent()` with the legacy three-argument signature `resolveContent(data, key, callback)` on affected Nodemailer versions (9.1.0 and earlier), since sandbox options `disableFileAccess` and `disableUrlAccess` are not honored when message content is resolved through this API.
Event History
Frequently Asked Questions
Which deployments are realistically exposed to this bypass?
Deployments using Nodemailer 9.1.0 or earlier are exposed only if plugin or application code calls the public MailMessage.resolveContent() API with its legacy three-argument signature to resolve untrusted message content. The normal transporter.sendMail() resolution paths are not affected.
What must an attacker control to exploit the issue?
An attacker must be able to influence content resolved through that API, such as html, text, or an attachment path or href. This can cause the server to read arbitrary local files or make outbound HTTP(S) requests despite enabled file- and URL-access restrictions.
Are disableFileAccess and disableUrlAccess effective in the affected code path?
No. When the legacy resolveContent(data, key, callback) signature is used, the message-level disableFileAccess and disableUrlAccess settings are discarded, so the relevant access-control checks are skipped.
What can be done if upgrading is not immediately possible?
Avoid resolving untrusted html, text, attachment paths, or attachment href values through the legacy three-argument MailMessage.resolveContent() call. Use the unaffected normal transporter.sendMail() paths where applicable, and restrict untrusted content from supplying local paths or URLs.
How can teams determine whether their application uses the vulnerable path?
Review application and plugin code for calls to MailMessage.resolveContent(data, key, callback), specifically the documented legacy three-argument form. Calls made only through transporter.sendMail() and its internal resolution paths are not affected by this issue.