From d74b6aeadfc2940581bc6472df66079d3758b72a Mon Sep 17 00:00:00 2001 From: "Abdullah." <125115953+mabdullahabaid@users.noreply.github.com> Date: Sun, 21 Jun 2026 18:05:00 +0500 Subject: [PATCH] fix(security): bump nodemailer to 9.0.1 (raw-option SSRF / file read) (#21903) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## fix(security): bump nodemailer to 9.0.1 (raw-option SSRF / file read) Resolves [Dependabot Alert #1518](https://github.com/twentyhq/twenty/security/dependabot/1518) and [#1519](https://github.com/twentyhq/twenty/security/dependabot/1519). ### What `nodemailer` `<= 9.0.0` lets the message-level `raw` option bypass `disableFileAccess`/`disableUrlAccess`, enabling **arbitrary file read** and **full-response SSRF** in the delivered message ([GHSA advisory](https://github.com/twentyhq/twenty/security/dependabot/1518), High). Patched in `9.0.1`. ### How — direct bump, no resolution - **twenty-server:** `nodemailer ^8.0.5 -> ^9.0.1` (major bump). - **seed-dependencies:** the application-package template `nodemailer ^8.0.5 -> ^9.0.1`; both `DEFAULT_PACKAGE_JSON_CHECKSUM` and `DEFAULT_YARN_LOCK_CHECKSUM` regenerated to match the recomputed seed files (the deps-layer cache key). ### Compatibility — verified nothing breaks It is a major upgrade, so the 9.0 breaking change was checked against the current tree. The only behavior change is **stricter TLS validation when nodemailer fetches remote content** (attachment `href`/`path` URLs, built-in OAuth2 token endpoints, HTTP/HTTPS proxy `CONNECT`). None of those paths are reachable here: - Attachments are passed as **content buffers**, never `path`/`href`. - Gmail OAuth uses **googleapis**, not nodemailer's built-in OAuth2. - No proxy on any transport. - The SMTP socket TLS is governed separately (unchanged). Verification: `typecheck twenty-server` passes (with `@types/nodemailer ^7.0.3`), and the `email-sender`, `gmail-message-outbound`, and `imap-smtp-caldav-connection` suites pass (10 tests). ### Not covered (follow-up) Root alert **#1521** will stay open: `imapflow@1.3.6` exact-pins `nodemailer@8.0.10`. The clean fix is `imapflow 1.4.2` (which pins nodemailer `9.0.1`), but it published 2026-06-19 and is **age-gated until ~2026-06-22** — it will land then as a parent-bump (no resolution). ### Verification - `nodemailer` resolves to `9.0.1` for twenty-server; seed lockfile has `9.0.1`; both seed checksums match the canonical recompute. - `yarn install --immutable` passes. --- packages/twenty-server/package.json | 2 +- .../constants/seed-dependencies/package.json | 2 +- .../constants/seed-dependencies/yarn.lock | 10 +++++----- .../get-default-application-package-fields.util.ts | 4 ++-- yarn.lock | 10 +++++----- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/twenty-server/package.json b/packages/twenty-server/package.json index 723a3308de..0d6af0a851 100644 --- a/packages/twenty-server/package.json +++ b/packages/twenty-server/package.json @@ -138,7 +138,7 @@ "ms": "2.1.3", "nest-commander": "^3.19.1", "node-ical": "^0.21.0", - "nodemailer": "^8.0.5", + "nodemailer": "^9.0.1", "openapi-types": "12.1.3", "openid-client": "^5.7.0", "otplib": "^12.0.1", diff --git a/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/package.json b/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/package.json index 19d0c3832c..16c9eecce4 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/package.json +++ b/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/package.json @@ -36,7 +36,7 @@ "lodash.pickby": "^4.6.0", "lodash.snakecase": "^4.1.1", "lodash.upperfirst": "^4.3.1", - "nodemailer": "^8.0.5", + "nodemailer": "^9.0.1", "psl": "^1.15.0", "sharp": "^0.34.5", "uuid": "^11.1.1", diff --git a/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/yarn.lock b/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/yarn.lock index 9c8db8e20a..b1bb12ecca 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/yarn.lock +++ b/packages/twenty-server/src/engine/core-modules/application/application-package/constants/seed-dependencies/yarn.lock @@ -2207,10 +2207,10 @@ __metadata: languageName: node linkType: hard -"nodemailer@npm:^8.0.5": - version: 8.0.10 - resolution: "nodemailer@npm:8.0.10" - checksum: 10c0/b96fd2ea7146de58141219061e094509fd0f19aac5ac86ac35d9ce9c479dbf6c12b143fa7e7050a1be539a3542eb59520c33aabf5a119c8d28fc7d151bde329f +"nodemailer@npm:^9.0.1": + version: 9.0.1 + resolution: "nodemailer@npm:9.0.1" + checksum: 10c0/4213f01aa211127c1ce33243c5e45e7f831601a933d03fa864cd827b1bd5ea2782cb4b43722bee7028cbc193733d9802dad1120fe67181448eb0b7de52218a37 languageName: node linkType: hard @@ -2537,7 +2537,7 @@ __metadata: lodash.pickby: "npm:^4.6.0" lodash.snakecase: "npm:^4.1.1" lodash.upperfirst: "npm:^4.3.1" - nodemailer: "npm:^8.0.5" + nodemailer: "npm:^9.0.1" psl: "npm:^1.15.0" sharp: "npm:^0.34.5" uuid: "npm:^11.1.1" diff --git a/packages/twenty-server/src/engine/core-modules/application/application-package/utils/get-default-application-package-fields.util.ts b/packages/twenty-server/src/engine/core-modules/application/application-package/utils/get-default-application-package-fields.util.ts index 3096238502..67196a8cc6 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-package/utils/get-default-application-package-fields.util.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-package/utils/get-default-application-package-fields.util.ts @@ -7,8 +7,8 @@ import { SEED_DEPENDENCIES_DIRNAME } from 'src/engine/core-modules/application/a // To regenerate: use logicFunctionCreateHash from logic-function-create-hash.utils. // package.json: hash(JSON.stringify(JSON.parse(content))). yarn.lock: hash(content). // Both use first 32 chars of SHA512 hex digest. -const DEFAULT_PACKAGE_JSON_CHECKSUM = '6ec55ff4ec55f433415417c845bc5c04'; -const DEFAULT_YARN_LOCK_CHECKSUM = '57cfae64905e3804cc1df95a0fa0707d'; +const DEFAULT_PACKAGE_JSON_CHECKSUM = 'c05f7f23a158d61caa123c55b455530a'; +const DEFAULT_YARN_LOCK_CHECKSUM = 'bc70bafdc23193461aeaf7e35b2ee786'; export type DefaultApplicationPackageFields = { packageJsonChecksum: string; diff --git a/yarn.lock b/yarn.lock index 12e7112c54..c7cf746f5a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -44137,10 +44137,10 @@ __metadata: languageName: node linkType: hard -"nodemailer@npm:^8.0.5": - version: 8.0.11 - resolution: "nodemailer@npm:8.0.11" - checksum: 10c0/19229216c63a32eae59d7b39f3dffeba20be317f2335d08d86fb70bd01845a1bf108fecd019c0e90ef186e3d9177cf478192b333cf38620ad0f8c7a6e1e5ae05 +"nodemailer@npm:^9.0.1": + version: 9.0.1 + resolution: "nodemailer@npm:9.0.1" + checksum: 10c0/4213f01aa211127c1ce33243c5e45e7f831601a933d03fa864cd827b1bd5ea2782cb4b43722bee7028cbc193733d9802dad1120fe67181448eb0b7de52218a37 languageName: node linkType: hard @@ -54349,7 +54349,7 @@ __metadata: ms: "npm:2.1.3" nest-commander: "npm:^3.19.1" node-ical: "npm:^0.21.0" - nodemailer: "npm:^8.0.5" + nodemailer: "npm:^9.0.1" openapi-types: "npm:12.1.3" openid-client: "npm:^5.7.0" otplib: "npm:^12.0.1"