Skip to content

Commit 82efcf8

Browse files
authored
fix: security issue from nodemailer (#13304)
1 parent 798c3d5 commit 82efcf8

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

packages/next-auth/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
"peerDependencies": {
102102
"@auth/core": "0.34.2",
103103
"next": "^12.2.5 || ^13 || ^14 || ^15",
104-
"nodemailer": "^6.6.5",
104+
"nodemailer": "^7.0.7",
105105
"react": "^17.0.2 || ^18 || ^19",
106106
"react-dom": "^17.0.2 || ^18 || ^19"
107107
},

packages/next-auth/src/core/routes/signin.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,39 @@ export default async function signin(params: {
3939
const normalizer: (identifier: string) => string =
4040
provider.normalizeIdentifier ??
4141
((identifier) => {
42+
const trimmedEmail = identifier.trim()
43+
44+
// Validate email format according to RFC 5321/5322
45+
// Reject emails with quotes in the local part to prevent address parser exploits
46+
// Reject multiple @ symbols which could indicate an exploit attempt
47+
const atCount = (trimmedEmail.match(/@/g) ?? []).length
48+
if (atCount !== 1) {
49+
throw new Error("Invalid email address format.")
50+
}
51+
52+
// Check for quotes in the email address which could be used for exploits
53+
if (trimmedEmail.includes('"')) {
54+
throw new Error("Invalid email address format.")
55+
}
56+
4257
// Get the first two elements only,
4358
// separated by `@` from user input.
44-
let [local, domain] = identifier.toLowerCase().trim().split("@")
59+
let [local, domain] = trimmedEmail.toLowerCase().split("@")
60+
61+
// Validate that both local and domain parts exist and are non-empty
62+
if (!local || !domain) {
63+
throw new Error("Invalid email address format.")
64+
}
65+
4566
// The part before "@" can contain a ","
4667
// but we remove it on the domain part
4768
domain = domain.split(",")[0]
69+
70+
// Additional validation: domain must have at least one dot
71+
if (!domain.includes(".")) {
72+
throw new Error("Invalid email address format.")
73+
}
74+
4875
return `${local}@${domain}`
4976
})
5077

0 commit comments

Comments
 (0)