Repository navigation
fix(deps): update dependency nodemailer to v9.1.1 [security] - #187
Merged
Merged
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
fbuireu
pushed a commit
that referenced
this pull request
Sep 9, 2026
## [1.27.1](v1.27.0...v1.27.1) (2026-09-09) ### Bug Fixes * **deps:** update dependency nodemailer to v9.1.1 [security] ([#187](#187)) ([82a7a74](82a7a74))
Owner
|
🎉 This PR is included in version 1.27.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
9.1.0→9.1.1Nodemailer: resolveContent() on a MailMessage bypasses disableFileAccess/disableUrlAccess when called with the legacy signature
GHSA-8m3c-c648-2xjj
More information
Details
Summary
Nodemailer's
disableFileAccess/disableUrlAccessoptions are a security sandbox that lets an application forbid untrusted message content (html/text/attachmentpath/href) from reading local files or making outbound HTTP(S) requests. The fix for GHSA-wqvq-jvpq-h66f (commit5f69497) threaded these flags through the library's internal resolution paths (MailMessage.resolveAll()and_convertDataImages()), but the public plugin APIMailMessage.resolveContent(...args)(lib/mailer/mail-message.js:41-43) remains a raw passthrough toshared.resolveContent().When called with the documented legacy signature
mail.resolveContent(data, key, callback),shared.resolveContentnormalizes the missing options argument to an empty object (options = options || {},lib/shared/index.js:530). The message-level flags that theMailMessageconstructor already copied intomail.data(lib/mailer/mail-message.js:34-38) are silently discarded, soresolveContentValueskips both access-control guards and reachesnmfetch(url)(SSRF,lib/shared/index.js:588) orfs.createReadStream(path)(arbitrary file read,lib/shared/index.js:597).A plugin or application code that resolves message content through the documented API (the same API the library's own
_convertDataImagesuses, threading the flags explicitly) thereby bypasses the sandbox an application deliberately enabled.Details
Root cause. The
MailMessageconstructor stores the transporter-level sandbox flags on the message object (lib/mailer/mail-message.js:34-38):The public resolver is a pure passthrough (
lib/mailer/mail-message.js:41-43):shared.resolveContentsupports the legacy 3-argument signature and collapses the missing options to{}(lib/shared/index.js:524-530):resolveContentValuethen checksoptions.disableUrlAccess/options.disableFileAccess(lib/shared/index.js:581/:590), bothundefinedfor the legacy signature, so it falls through tonmfetch(:588) orfs.createReadStream(:597).Contrast with the fixed paths.
resolveAll()(lib/mailer/mail-message.js:112-115) and_convertDataImages()(lib/mailer/index.js:437-440) both pass the message flags explicitly. The MIME streaming path (lib/mime-node/index.js:1059-1077) also honors the flags. So an application that enables the sandbox and then callstransporter.sendMail()is protected; the bypass appears only when message content is resolved through the public legacy-signature API — which is the documented plugin usage (theresolveContentJSDoc atlib/shared/index.js:510-523states it is "useful when you want to create a plugin that needs a content value").Affected versions. Confirmed on
9.1.0(HEADefd6e29c10c6e0c25c57bd2f2a71302838235a4f, the current npm latest). The gap was introduced by the GHSA-wqvq-jvpq-h66f fix and is still present; the public API has no regression coverage (test/mailer/mail-message-test.jscontains noresolveContenttest).PoC
Requires:
nodemailer@9.1.0, a readable local file, and any reachable HTTP endpoint (loopback suffices). Non-destructive; no network egress beyond a local listener.Observed output on the audit environment (Node 22,
nodemailer@9.1.0):The negative controls (
resolveAll, andresolveContentwith explicit{ disableFileAccess: true }) returnEFILEACCESS, proving the sandbox works on the protected paths and only the legacy-signature passthrough is bypassed. The same bypass reproduces inside a realtransporter.sendMail()flow when acompileplugin callsmail.resolveContent(mail.data, 'html', cb)/mail.resolveContent(mail.data.attachments, 0, cb).Impact
An application that enables
disableFileAccess/disableUrlAccessto contain untrusted message content and that resolves content through the documented plugin API (mail.resolveContent(data, key, callback)) has its sandbox silently bypassed:html/attachmentpathpointing at a server file (/etc/passwd,.env, key material) is read and returned to the caller / delivered in the message.hrefpointing at an internal or loopback URL is fetched from the application host.Reachability precondition: the sandbox flags must be enabled (default off) and the application or its plugin must invoke the documented legacy-signature API on attacker-influenced data. The default
transporter.sendMail()path remains protected, so this is a defense-in-depth gap in the library's own access-control enforcement rather than a default-flow bypass. It is the same vulnerability class as the previously accepted GHSA-wqvq-jvpq-h66f (CVE-2026-82660) and GHSA-p6gq-j5cr-w38f (CVE-2026-82659), on a distinct third code path.Severity
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
Release Notes
nodemailer/nodemailer (nodemailer)
v9.1.1Compare Source
Bug Fixes
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.