Opened 12 months ago

Closed 10 months ago

Last modified 10 months ago

#34961 closed Cleanup/optimization (wontfix)

Add a max_length parameter to EmailValidator

Reported by: jecarr Owned by: nobody
Component: Core (Other) Version: 4.2
Severity: Normal Keywords:
Cc: Mariusz Felisiak Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

  • I was using EmailValidator on a string
  • It wasn't on an EmailField (which has a default max-length of 254)
  • But I did want some consistency with EmailFields I have elsewhere in my application
  • The EmailValidator allows a max-length of 320 (as is mentioned in the docs too)
  • Apologies if I've misunderstood design-reasons around this, but I wondered if we could have in EmailValidator a max_length property?
  • So if the 320-max-length is intentional, have EmailValidator's init function take message=None, code=None, allowlist=None, max_length=320 as its default parameters. And then use a property max_length in the length-check.

Change History (9)

comment:1 by Natalia Bidart, 12 months ago

Resolution: wontfix
Status: newclosed

Hello, thank you for your report.

I'm not sure I understand your use case. Is it that you are not using EmailField but you do use the EmailValidator in other type of field? And if so, you'd like to set a length smaller than 320 chars?

If that's correct, you could define a subclass of EmailValidator and check for the smaller value:

class MyEmailValidator(EmailValidator):

    def __call__(self, value):
        if value and len(value) > your_limit_smaller_than_320:
            raise ValidationError(self.message, code=self.code, params={"value": value})
        super().__call__(value)

I'll be closing this ticket as wontfix following the Ticket Triaging policy, but if I'm not understanding your use case properly, please provide more details so we can re-asses. A small Django project as a example would be great, or at least models showcasing the use case.

Thanks!

comment:2 by jecarr, 12 months ago

Thanks for the quick reply and solution!

You are correct with my use case and your solution would apply to my scenario. (I'm validating a non-Django-Field variable, a string.)

I initially raised the ticket because EmailField has a max-length of 254 and EmailValidator has a max-length of 320. (I am aware this is not a bug as all is still working.)

My intention was to have consistency with these two so within the Django codebase - regardless of my codebase/other applications - it does not look like two different max-lengths for email addresses are suggested. Additionally, I thought of others who may also want consistency with having max-lengths of 254 elsewhere in their application only to use Django's EmailValidator separately (not on an EmailField) to find longer email addresses accepted.

I did wonder if the two different max-lengths were unintentional and thought an approach would be to drop the EmailValidator max-length to match that of EmailField's max-length or vice-versa. But I appreciate this could cause breaking changes to existing applications hence my initial suggestion.

As this is now a wontfix and for my understanding of the codebase, I'll ask why the two different max-lengths for email addresses? Is it because with Fields we want to be stricter with max-lengths?

Version 0, edited 12 months ago by jecarr (next)

in reply to:  2 comment:3 by Natalia Bidart, 12 months ago

Cc: Mariusz Felisiak added

Replying to jecarr:

I did wonder if the two different max-lengths were unintentional and thought an approach would be to drop the EmailValidator max-length to match that of EmailField's max-length or vice-versa. But I appreciate this could cause breaking changes to existing applications hence my initial suggestion.

As this is now a wontfix and for my understanding of the codebase, I'll ask why the two different max-lengths for email addresses? Is it because with Fields we want to be stricter with max-lengths?

Thank you for reaching out after you noticed the different max lengths allowed for the EmailField and the EmailValidator. I don't have the exact answer for "why the two different max-lengths for email addresses" but I can share some facts:

  1. The validator EmailValidator is a generic email validator that is used to validate email addresses using regular expressions. Recently, the maximum allowed length for validating a email was limited to 320 chars following a security release from July to prevent potential DoS attacks when validating extremely long strings.
  1. The form field EmailField is an abstraction of an HTML input, basically a char field represented as <input type="email" maxlength="...>. The default max_length for this field was set to 320 in the same security release I mentioned above (before that, max_length was optional and unset for this field).
  1. The model field EmailField is just a CharField with a default max_length (254 as you noticed) and a configured validator (EmailValidator). I can see how this difference in the maximum allowed length raises questions.

So, in all honesty, when I closed the ticket yesterday I wasn't considering the two EmailFields (the model and the form fields). Now that I write this summary, and that I see that the form field's max_length was changed to match the length of the validator but not the model field, I do wonder if we should. I'll cc Mariusz to see what he thinks since he implemented the original 320 char limit.

Glad you asked more questions about this!

comment:4 by jecarr, 10 months ago

Resolution: wontfix
Status: closednew

comment:5 by Mariusz Felisiak, 10 months ago

Resolution: wontfix
Status: newclosed

The default maximum length of an email is 320 characters per RFC 3696 section 3, that's why EmailValidator that checks if string is an email uses this boundary. There is no need to add max_length argument. If you want to use a lower value you should add MaxLengthValidator that Django will add automatically when you define max_length on model fields.

We could consider changing the default to 254 characters because it was changed in RFC 5321, but this ticket is about adding max_length to the validator, so it's "wontix" for me.

in reply to:  5 ; comment:6 by Natalia Bidart, 10 months ago

Replying to Mariusz Felisiak:

We could consider changing the default to 254 characters because it was changed in RFC 5321, but this ticket is about adding max_length to the validator, so it's "wontix" for me.

Mariusz, I checked the RFC5321 and as per my reading, the recommendation is: for the local part of the email address (before the @ symbol), no more than 64 characters long. For the domain part, no more than 255 characters. That adds up to 319 plus the @ sign, so 320chars as you already added to the EmailValidator. Where is it that the max length was changed to 254?

in reply to:  6 comment:7 by Mariusz Felisiak, 10 months ago

Replying to Natalia Bidart:

Mariusz, I checked the RFC5321 and as per my reading, the recommendation is: for the local part of the email address (before the @ symbol), no more than 64 characters long. For the domain part, no more than 255 characters. That adds up to 319 plus the @ sign, so 320chars as you already added to the EmailValidator. Where is it that the max length was changed to 254?

Yes, but a total size limit is defined in 4.5.3.1.3:

The maximum total length of a reverse-path or forward-path is 256 octets (including the punctuation and element separators).

RFC 3696 was corrected here.

comment:8 by Natalia Bidart, 10 months ago

Thank you Mariusz, I'll triage #35119 accordingly then.

comment:9 by Mariusz Felisiak, 10 months ago

So 320-length emails are theoretically valid, but useless.

Note: See TracTickets for help on using tickets.
Back to Top