Skip to content

Commit 8f3b2c7

Browse files
authored
fix: security issue from nodemailer (#13305)
1 parent 240e343 commit 8f3b2c7

File tree

5 files changed

+38
-11
lines changed

5 files changed

+38
-11
lines changed

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
"peerDependencies": {
7777
"@simplewebauthn/browser": "^9.0.1",
7878
"@simplewebauthn/server": "^9.0.2",
79-
"nodemailer": "^6.8.0"
79+
"nodemailer": "^7.0.7"
8080
},
8181
"peerDependenciesMeta": {
8282
"@simplewebauthn/browser": {

packages/core/src/lib/actions/signin/send-token.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,32 @@ export async function sendToken(
9393

9494
function defaultNormalizer(email?: string) {
9595
if (!email) throw new Error("Missing email from request body.")
96+
97+
const trimmedEmail = email.toLowerCase().trim()
98+
99+
// Reject email addresses with quotes to prevent address parser confusion
100+
// This prevents attacks like "[email protected]"@victim.com
101+
if (trimmedEmail.includes('"')) {
102+
throw new Error("Invalid email address format.")
103+
}
104+
96105
// Get the first two elements only,
97106
// separated by `@` from user input.
98-
let [local, domain] = email.toLowerCase().trim().split("@")
107+
let [local, domain] = trimmedEmail.split("@")
108+
109+
// Validate that we have exactly 2 parts (local and domain)
110+
if (!local || !domain || trimmedEmail.split("@").length !== 2) {
111+
throw new Error("Invalid email address format.")
112+
}
113+
99114
// The part before "@" can contain a ","
100115
// but we remove it on the domain part
101116
domain = domain.split(",")[0]
117+
118+
// Additional validation: domain should not be empty after comma split
119+
if (!domain) {
120+
throw new Error("Invalid email address format.")
121+
}
122+
102123
return `${local}@${domain}`
103124
}

packages/frameworks-sveltekit/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
"@simplewebauthn/browser": "^9.0.1",
5858
"@simplewebauthn/server": "^9.0.3",
5959
"@sveltejs/kit": "^1.0.0 || ^2.0.0",
60-
"nodemailer": "^6.6.5",
60+
"nodemailer": "^7.0.7",
6161
"svelte": "^3.54.0 || ^4.0.0 || ^5.0.0-0"
6262
},
6363
"peerDependenciesMeta": {

packages/next-auth/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
"@simplewebauthn/browser": "^9.0.1",
9393
"@simplewebauthn/server": "^9.0.2",
9494
"next": "^14.0.0-0 || ^15.0.0-0",
95-
"nodemailer": "^6.6.5",
95+
"nodemailer": "^7.0.7",
9696
"react": "^18.2.0 || ^19.0.0-0"
9797
},
9898
"peerDependenciesMeta": {
@@ -110,7 +110,7 @@
110110
"@types/react": "18.0.37",
111111
"dotenv": "^10.0.0",
112112
"next": "15.3.1",
113-
"nodemailer": "^6.9.3",
113+
"nodemailer": "^7.0.7",
114114
"react": "^18.2.0"
115115
}
116116
}

pnpm-lock.yaml

Lines changed: 12 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)