zod icon indicating copy to clipboard operation
zod copied to clipboard

Email validation does not validate emails according to RFC standards

Open mpiltz opened this issue 6 months ago • 2 comments

It seems that Zod email validation accepts emails that are not conforming to RFC specifications.

" In addition to restrictions on syntax, there is a length limit on email addresses. That limit is a maximum of 64 characters (octets) in the "local part" (before the "@") and a maximum of 255 characters (octets) in the domain part (after the "@") for a total length of 320 characters. Systems that handle email should be prepared to process addresses which are that long, even though they are rarely encountered."

So the issues is that Zod does not count total number of chars or separate "local part" and "domain part".

Should I open a PR or is this something that is already on someones table?

mpiltz avatar Jan 18 '24 08:01 mpiltz

Hello,

I'd like to complete this RFC issue : Special characters are not (all) allowed when using z.email(), such as quote (" ' ") :

"[...]local-parts may consist of any combination of alphabetic characters, digits, or any of the special characters ! # $ % & ' * + - / = ? ^ _ ` . { | } ~"

( see https://www.rfc-editor.org/rfc/rfc3696)

camboui avatar Feb 08 '24 16:02 camboui

Connected with this, I just got a Zod validation error on the email address containing an apostrophe, which @camboui just pointed out is permitted.


I see that's covered by #2888 , which has a PR.

kernwig avatar Mar 01 '24 19:03 kernwig

Hi there! It seems like this is related, so I'll share.

I just found out that Zod allows commas in the local part of the email. Example: john,[email protected]. A little research tells me commas are only allowed if they're wrapped in quotes.

EDIT: my bad, looks like this is also fixed in this PR #3286.

aidasbui avatar Mar 11 '24 16:03 aidasbui

Ran into this today with this example failing the regex but allowed in the RFC: email11/[email protected]. Forward slash is valid but does not match via Zod.

cbeardsmore avatar Apr 08 '24 20:04 cbeardsmore

It's an old comment, but it may still be relevant: https://github.com/colinhacks/zod/pull/3218#issuecomment-1945087788

fernandollisboa avatar Apr 09 '24 15:04 fernandollisboa

This is intended, see #2157 for the justification.

You can use .superRefine() for custom behavior here.

const emailRegex =
  /^(?!\.)(?!.*\.\.)([A-Z0-9_'+-\.]*)[A-Z0-9_'+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;

const emailSchema = z.string().superRefine((data, ctx) => {
  if (!emailRegex.test(data)) {
    ctx.addIssue({
      code: z.ZodIssueCode.invalid_string,
      message: "Invalid email address",
      validation: "email",
    });
  }
});

colinhacks avatar Apr 16 '24 23:04 colinhacks