diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index f65c65d2..2fbd12e0 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -94,9 +94,9 @@ } }, "node_modules/nodemailer": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-10.1.0.tgz", - "integrity": "sha512-fXW8AulB25aOTuwfRYV6lqHyfz2VM4rr4SGXH03mE7x5znEUpzL5mu6anARUpZN7744Ziwkmr4AxSLPJsBQspg==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-10.1.1.tgz", + "integrity": "sha512-pbqZRoeYUO+1E8TJ/11WeY4D2EVujj1hsYjz3qff/vUFDtGnmi7p3iqzTFslYOfQ6PnjVcWxx/CIUSHCSrO/QA==", "license": "MIT-0", "engines": { "node": ">=20.0.0" diff --git a/node_modules/nodemailer/CHANGELOG.md b/node_modules/nodemailer/CHANGELOG.md index 6ecd547c..5a434aa8 100644 --- a/node_modules/nodemailer/CHANGELOG.md +++ b/node_modules/nodemailer/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGELOG +## [10.1.1](https://github.com/nodemailer/nodemailer/compare/v10.1.0...v10.1.1) (2026-10-14) + + +### Bug Fixes + +* **fetch:** strip credentials on any cross-origin redirect ([a15360c](https://github.com/nodemailer/nodemailer/commit/a15360cd2cd12e4670e96ab0b7290e8c862391cf)) + ## [10.1.0](https://github.com/nodemailer/nodemailer/compare/v10.0.16...v10.1.0) (2026-10-10) diff --git a/node_modules/nodemailer/SECURITY.md b/node_modules/nodemailer/SECURITY.md index 66063909..056daa3d 100644 --- a/node_modules/nodemailer/SECURITY.md +++ b/node_modules/nodemailer/SECURITY.md @@ -1,7 +1,9 @@ # Security Policy -Nodemailer is a widely deployed, zero-dependency e-mail library. We take security -reports seriously and aim to respond quickly. +Nodemailer is a widely deployed, zero-dependency email library. We welcome +responsible reports of vulnerabilities that present a credible security risk to +users. Please distinguish security vulnerabilities from ordinary bugs, unusual +edge cases, and hardening suggestions. ## Supported Versions @@ -17,45 +19,119 @@ the supported way to receive security updates. If you are on an older major, please upgrade. See the migration notes at before updating. +## What Qualifies as a Security Vulnerability + +A security report should identify a realistic way for an attacker to cross a +security boundary in a supported version of Nodemailer. Unexpected behavior, +a failing test, or a technically correct proof of concept is not sufficient on +its own to establish security impact. + +In particular, explain: + +- **Attacker capabilities:** Who is the attacker, and what inputs, systems, or + responses can they control _without_ already having the privileges or secrets + they are trying to gain? +- **Attack path:** How does attacker-controlled input reach the affected code + through a supported Nodemailer API or a realistic application integration? +- **Prerequisites:** What configuration and user actions are required? If the + attack depends on unusual options or deliberately malformed input, explain + why those conditions could arise in a real application. +- **Impact:** What confidentiality, integrity, or availability boundary is + crossed, and what can the attacker achieve as a result? + +A vulnerability involving an optional or less common feature can still qualify +if these conditions are met. Conversely, the existence of a defensive check in +the code does not, by itself, establish that every bypass of that check has a +realistic security impact. + ## Reporting a Vulnerability -**Please do not report security vulnerabilities through public GitHub issues, -pull requests, or discussions.** +**Do not disclose suspected exploitable vulnerabilities through public GitHub +issues, pull requests, or discussions before coordinating with the maintainer.** Report privately through one of the following channels: -1. **GitHub Security Advisories (preferred).** Open a private report at - . This keeps - the discussion private until a fix is published and lets us credit you. -2. **Email.** Send details to **andris@reinman.eu** (the contact listed in - [`SECURITY.txt`](SECURITY.txt)). Encrypt sensitive details if possible. +1. **GitHub Security Advisories (preferred):** + . +2. **Email:** **andris@reinman.eu**, as listed in + [`SECURITY.txt`](SECURITY.txt). Encrypt sensitive details if possible. -When reporting, please include as much of the following as you can: +### Required Information -- The affected version(s) and environment (Node.js version, OS). -- The component involved (e.g. SMTP connection, address parsing, MIME/header - generation, DKIM). -- A clear description of the issue and its impact (e.g. header/SMTP command - injection, information disclosure, DoS). -- A minimal proof of concept or reproduction steps. -- Any suggested remediation, if you have one. +Please provide enough information to evaluate both the defect and its security +impact. Reports should include: -Nodemailer is maintained by a single person, so there is no guaranteed response -time: sometimes reports are handled within hours, sometimes they take longer. -Accepted issues are fixed in a new release and coordinated through a GitHub -Security Advisory, and reporters who wish to be named are credited. +1. The affected Nodemailer version or commit, Node.js version, and relevant + configuration. +2. A concise description of the issue and the affected public API or code path. +3. A minimal, tested reproduction, including steps to run it, expected behavior, + and observed behavior. +4. A concrete threat model: attacker control, prerequisites, trust boundary, and + resulting impact. Clearly distinguish what your reproduction proves from what + you believe might be possible. +5. An explanation of why the issue affects applications beyond a deliberately + constructed test setup, where this is not obvious. -## CVEs +A suggested fix is welcome but does not replace an explanation of exploitability. +A complete real-world exploit is not always necessary, but the report must make +a credible security impact clear. -We track and disclose vulnerabilities through GitHub Security Advisories. We do -not request or manage CVE identifiers ourselves. If you need a CVE assigned for a -reported issue, please request one yourself, for example through GitHub's own -CVE request flow on the published advisory, or another CNA. +### Reports That May Be Treated as Ordinary Bugs + +The following generally do **not** qualify for private security handling unless +you can demonstrate an additional, meaningful security boundary crossing: + +- Issues that require the attacker to control trusted application code, + administrator-only configuration, or the secret they supposedly extract. +- Problems caused solely by application-level misuse, exposed credentials, or + insecure deployment choices outside Nodemailer's control. +- Contrived proof-of-concept setups where the tester controls both sides of a + request, without explaining how a separate attacker could trigger the issue. +- Parser quirks, unexpected behavior, and bypasses of internal checks with no + demonstrated security impact. +- Speculative findings based only on static analysis or an automated tool's + assessment, without a verified reproduction and credible attack scenario. + +These may still be valid bugs and may be considered through the normal issue +tracker. Please coordinate before making any potentially exploitable details +public. Classification as a bug does not guarantee a fix or a particular +priority. + +### Automated and AI-Assisted Reports + +Automated analysis and AI tools are welcome as research aids, but the person +submitting a report is responsible for verifying its claims. **Do not submit +bulk, unverified, or speculative AI-generated findings.** Test each finding +against a supported release and establish the actual security impact. Reports +that do not meet the requirements above may be closed without further +investigation or individual feedback; they can be resubmitted with stronger +evidence. + +## Triage and Disclosure + +Nodemailer is maintained by a single person, and there is **no guaranteed +response or resolution time**. Reports are prioritized based on demonstrated +impact, exploitability, affected usage, and available maintenance resources. + +A private report does not automatically become a security advisory. Confirmed +vulnerabilities may be fixed and disclosed through GitHub Security Advisories; +other findings may be closed, deferred, or handled as ordinary bugs. Please do +not disclose details of an unresolved, potentially exploitable issue publicly +without coordinating with the maintainer. + +## CVEs and Credit + +We do not request or manage CVE identifiers. A report being acknowledged, a bug +being fixed, or a pull request being merged does **not** mean that Nodemailer +has confirmed a security vulnerability or endorsed a CVE assignment. We do not +guarantee advisories, CVE identifiers, or public credit for reports. For +confirmed vulnerabilities disclosed through an advisory, substantive reporters +may be credited if they wish. ## Scope In scope: the `nodemailer` package source in this repository: message and MIME -generation, SMTP/LMTP client behaviour, address parsing, header handling, DKIM +generation, SMTP/LMTP client behavior, address parsing, header handling, DKIM signing, and the bundled transports. Out of scope: vulnerabilities in your own application code, misconfiguration of diff --git a/node_modules/nodemailer/dist/cjs/fetch/index.js b/node_modules/nodemailer/dist/cjs/fetch/index.js index a446f546..6a5a848d 100644 --- a/node_modules/nodemailer/dist/cjs/fetch/index.js +++ b/node_modules/nodemailer/dist/cjs/fetch/index.js @@ -116,6 +116,10 @@ function parseFetchUrl(url) { } return parsed; } +// the port a request to the URL goes to, explicit or the default of its scheme +function fetchPort(parsed) { + return parsed.port ? Number(parsed.port) : parsed.protocol === 'https:' ? 443 : 80; +} function nmfetch(url, options) { options = options || {}; options.fetchRes = options.fetchRes || new node_stream_1.PassThrough(); @@ -232,7 +236,7 @@ function nmfetch(url, options) { method, host: parsed.hostname, path: parsed.path, - port: parsed.port ? parsed.port : parsed.protocol === 'https:' ? 443 : 80, + port: fetchPort(parsed), headers, // Validate TLS certificates by default. Callers that genuinely need to // reach a self-signed/internal host opt out explicitly with @@ -334,17 +338,19 @@ function nmfetch(url, options) { // the shared fetchRes once it times out. Callers listen with req.once(). return fail(new Error('Unsupported protocol for URL ' + redirectUrl), redirectUrl); } - // Do not forward credentials when the redirect leaves the original - // security context: a different host, or a downgrade from https to - // http (which would otherwise put them on the wire in cleartext). - // Strip sensitive request headers so an attacker who controls the - // redirect target cannot harvest them. - const crossHost = redirectParsed.hostname !== parsed.hostname; - const downgrade = parsed.protocol === 'https:' && redirectParsed.protocol === 'http:'; - if (options.headers && (crossHost || downgrade)) { + // Do not forward credentials when the redirect leaves the origin: a different + // scheme, host or port is a different security context (an https to http + // downgrade would also put them on the wire in cleartext). Strip sensitive + // request headers so an attacker who controls the redirect target cannot + // harvest them. + const crossOrigin = redirectParsed.protocol !== parsed.protocol || + redirectParsed.hostname !== parsed.hostname || + fetchPort(redirectParsed) !== fetchPort(parsed); + if (options.headers && crossOrigin) { const sensitive = ['authorization', 'cookie', 'proxy-authorization']; Object.keys(options.headers).forEach(key => { - if (sensitive.includes(key.toLowerCase())) { + // normalized the way the request headers are built above, a padded name is sent too + if (sensitive.includes(key.toLowerCase().trim())) { delete options.headers[key]; } }); diff --git a/node_modules/nodemailer/dist/cjs/package-info.d.ts b/node_modules/nodemailer/dist/cjs/package-info.d.ts index 20d8d73a..80159c23 100644 --- a/node_modules/nodemailer/dist/cjs/package-info.d.ts +++ b/node_modules/nodemailer/dist/cjs/package-info.d.ts @@ -1,3 +1,3 @@ export declare const name = "nodemailer"; -export declare const version = "10.1.0"; +export declare const version = "10.1.1"; export declare const homepage = "https://nodemailer.com/"; diff --git a/node_modules/nodemailer/dist/cjs/package-info.js b/node_modules/nodemailer/dist/cjs/package-info.js index 2d173066..4a9004cb 100644 --- a/node_modules/nodemailer/dist/cjs/package-info.js +++ b/node_modules/nodemailer/dist/cjs/package-info.js @@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.homepage = exports.version = exports.name = void 0; exports.name = 'nodemailer'; -exports.version = '10.1.0'; +exports.version = '10.1.1'; exports.homepage = 'https://nodemailer.com/'; diff --git a/node_modules/nodemailer/dist/esm/fetch/index.js b/node_modules/nodemailer/dist/esm/fetch/index.js index 0ae1a40d..6d1cef31 100644 --- a/node_modules/nodemailer/dist/esm/fetch/index.js +++ b/node_modules/nodemailer/dist/esm/fetch/index.js @@ -78,6 +78,10 @@ function parseFetchUrl(url) { } return parsed; } +// the port a request to the URL goes to, explicit or the default of its scheme +function fetchPort(parsed) { + return parsed.port ? Number(parsed.port) : parsed.protocol === 'https:' ? 443 : 80; +} function nmfetch(url, options) { options = options || {}; options.fetchRes = options.fetchRes || new PassThrough(); @@ -194,7 +198,7 @@ function nmfetch(url, options) { method, host: parsed.hostname, path: parsed.path, - port: parsed.port ? parsed.port : parsed.protocol === 'https:' ? 443 : 80, + port: fetchPort(parsed), headers, // Validate TLS certificates by default. Callers that genuinely need to // reach a self-signed/internal host opt out explicitly with @@ -296,17 +300,19 @@ function nmfetch(url, options) { // the shared fetchRes once it times out. Callers listen with req.once(). return fail(new Error('Unsupported protocol for URL ' + redirectUrl), redirectUrl); } - // Do not forward credentials when the redirect leaves the original - // security context: a different host, or a downgrade from https to - // http (which would otherwise put them on the wire in cleartext). - // Strip sensitive request headers so an attacker who controls the - // redirect target cannot harvest them. - const crossHost = redirectParsed.hostname !== parsed.hostname; - const downgrade = parsed.protocol === 'https:' && redirectParsed.protocol === 'http:'; - if (options.headers && (crossHost || downgrade)) { + // Do not forward credentials when the redirect leaves the origin: a different + // scheme, host or port is a different security context (an https to http + // downgrade would also put them on the wire in cleartext). Strip sensitive + // request headers so an attacker who controls the redirect target cannot + // harvest them. + const crossOrigin = redirectParsed.protocol !== parsed.protocol || + redirectParsed.hostname !== parsed.hostname || + fetchPort(redirectParsed) !== fetchPort(parsed); + if (options.headers && crossOrigin) { const sensitive = ['authorization', 'cookie', 'proxy-authorization']; Object.keys(options.headers).forEach(key => { - if (sensitive.includes(key.toLowerCase())) { + // normalized the way the request headers are built above, a padded name is sent too + if (sensitive.includes(key.toLowerCase().trim())) { delete options.headers[key]; } }); diff --git a/node_modules/nodemailer/dist/esm/package-info.d.ts b/node_modules/nodemailer/dist/esm/package-info.d.ts index 20d8d73a..80159c23 100644 --- a/node_modules/nodemailer/dist/esm/package-info.d.ts +++ b/node_modules/nodemailer/dist/esm/package-info.d.ts @@ -1,3 +1,3 @@ export declare const name = "nodemailer"; -export declare const version = "10.1.0"; +export declare const version = "10.1.1"; export declare const homepage = "https://nodemailer.com/"; diff --git a/node_modules/nodemailer/dist/esm/package-info.js b/node_modules/nodemailer/dist/esm/package-info.js index 0ea5259b..e7d3bb05 100644 --- a/node_modules/nodemailer/dist/esm/package-info.js +++ b/node_modules/nodemailer/dist/esm/package-info.js @@ -1,4 +1,4 @@ // Generated by scripts/build.js from package.json. Do not edit by hand. export const name = 'nodemailer'; -export const version = '10.1.0'; +export const version = '10.1.1'; export const homepage = 'https://nodemailer.com/'; diff --git a/node_modules/nodemailer/package.json b/node_modules/nodemailer/package.json index 8ecdec04..6affd1ab 100644 --- a/node_modules/nodemailer/package.json +++ b/node_modules/nodemailer/package.json @@ -1,6 +1,6 @@ { "name": "nodemailer", - "version": "10.1.0", + "version": "10.1.1", "description": "Easy as cake e-mail sending from your Node.js applications", "type": "module", "main": "./dist/cjs/nodemailer.js", @@ -151,7 +151,7 @@ }, "homepage": "https://nodemailer.com/", "devDependencies": { - "@aws-sdk/client-sesv2": "3.1146.0", + "@aws-sdk/client-sesv2": "3.1151.0", "@types/node": "20.19.43", "bunyan": "1.8.15", "c8": "12.0.0", @@ -161,14 +161,14 @@ "libbase64": "1.3.2", "libmime": "5.4.7", "libqp": "2.1.2", - "mailauth": "7.1.1", - "prettier": "3.9.9", + "mailauth": "7.3.0", + "prettier": "3.9.10", "proxy": "1.0.2", "proxy-test-server": "1.0.0", - "smtp-server": "3.19.17", + "smtp-server": "3.19.21", "tsx": "4.23.15", "typescript": "6.0.3", - "typescript-eslint": "8.71.1" + "typescript-eslint": "8.71.2" }, "engines": { "node": ">=20.0.0"