Validator.js: IsEmail validates non RFC compliant

Created on 11 Oct 2018  路  14Comments  路  Source: validatorjs/validator.js

We are using sequelize which uses this library for email validation. Currently we experiencing the issue, that the valid email addresses we provide are taken as invalid. A few examples:

And probably more. Can you please fix that, it causes major issues in business use cases, cause local domain addresses with no tld, a number in the tld or just one character in the tld are very common.

馃嵖 discussion

Most helpful comment

My gripe with this is - [email protected] is valid but [email protected] is not.
IMHO - This is vendor-specific behavior which should not be get invoked OOTB. It should be a configuration option.
And if it does, it should give a more specific message: Gmail usernames cannot be less than 6 digits.

All 14 comments

You can use the option _require_tld_ and each of your cases passes.

Here is an example:

'use strict';

const validator = require('validator');

const validate = [
  'admin@admin',
  '[email protected]',
  '[email protected]'
];

validate.forEach(email => {
  const isEmail = validator.isEmail(email, {
    require_tld: false
  });

  console.log(email + ': ' + isEmail); // Each email passes
});

Output:

admin@admin: true
[email protected]: true
[email protected]: true

Ok, it actually doesn't solve the problem, but that lies in sequelize. Apart from that, I think it would be better that the default case is RFC compliant and not non compliant.

You can use the option _require_tld_ and each of your cases passes.

Here is an example:

'use strict';

const validator = require('validator');

const validate = [
  'admin@admin',
  '[email protected]',
  '[email protected]'
];

validate.forEach(email => {
  const isEmail = validator.isEmail(email, {
    require_tld: false
  });

  console.log(email + ': ' + isEmail); // Each email passes
});

Output:

admin@admin: true
[email protected]: true
[email protected]: true

This solution only works for the e-mails provided by @DerKnerd but e-mails from google with username part that has a length less than six don't work. And the bug is here

if (!isByteLength(username.replace('.', ''), { min: 6, max: 30 })) { return false; }
https://github.com/chriso/validator.js/blob/master/src/lib/isEmail.js#L65

would be good if you could fix this or I can submit a Pull Request

Can a gmail address be shorter than 6 characters? Do you have an example? I just tried:
screen shot 2018-10-12 at 11 29 16 am

(note that the screenshot is wrong, I originally tried 5 characters, and then I changed it to 6 and took the screenshot before I submitted again)

But is still a valid email address, the name of the function is misleading, cause it does vendor specific checks.

It doesn't do vendor specific checks unless you specify the option domain_specific_validation when calling isEmail()

I don't feel the function is misleading at all, it is well documented and works great.

Ok, I didn't see that part in the code. But still it doesn't work great, it is wrong in the default case. The RFCs very clearly defines how a valid email address should look like. Here is an article explaining it very thourgly https://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx/

Here are all relevnt RFCs:

So no,it doesn't work great. It works against the standards at least in the default case and this case should never represent something different than the standards.

@justinkalland you right google username minimum length is 6 but as @DerKnerd said you are doing vendor specific specif checks (https://github.com/chriso/validator.js/blob/master/src/lib/isEmail.js#L45) I tested without setting the option domain_specific_validation and it validates google rules. Also the only domain is google, so it should be something like apply_google_validations.
Anyways, this is a great library and we are just helping improving it.

The latest version of the library does not do domain-specific validation by default (it did at one point, but that was removed; see #873).

As for requiring a TLD, the validator tries to balance strict RFC validation with the fact that users expect emails to be a certain way in almost all cases. We have the same issue with isURL(). Most users would expect google.com to be a valid URL despite the missing protocol and path. We require a TLD here too, because if we were to drop the TLD requirement too then x would be considered a valid URL. Similarly, without the TLD requirement we would consider a@b to be a valid email address. This is tough to get right 鈥撀爐here are hostnames without a TLD that are commonly used (localhost, for example).

The TLD validator, enabled by default, requires at least two characters in the TLD, and does not allow numbers. Your example email hostnames admin.x and admin.de2 are not valid (they also don't exist/resolve). If you consider these to be valid email addresses, I'd like to hear why. We could potentially relax those requirements, or have an option to disable them.

Sidenote:
As much as GMail does not accept usernames less than 6 chars anymore, I believe we have valid GMail emails out there that are less than 6 chars. I tried sending an email to [email protected] and didn't get a fail like what I got with this one
screen shot 2018-10-25 at 11 38 16 am

We might need to revisit this; that's minor though.

@DerKnerd - I think the reason why the lib went for this default behavior is because RFC is broader than the general use-case.

I think it would be better that the default case is RFC compliant and not non compliant.

UPDATE: will need to fact check, based on this

@chriso for me this answer is fairly simple. The default case is to comply with the RFC because the internet is build on standards. It would probably be good idea to allow developers to also ask for a tld, but that shouldn't be the default case. I think it is not hard at all, just implement the RFC as the default case, and allow more restrictions by the developer.

My "home" is business development, and the Exchange Server by Microsoft allows nearly everything RFC compliant as an email address so the use cases are there out in the business world.

@profnandaa I know that even the w3c said the requirements by the RFC are to strict and browser implement a way simpler RegEx. But that doesn't change the fact, that it is more allowing than the validation of validator.js. This behavior causes problems in node.js environments, cause the browser says it is valid, but the server says it is not even though it is.

Thanks for the perspective, but I think we'll stick with the current behavior. Strict RFC validation is a non-goal of the library, and relaxing the current defaults would cause more issues than it would solve.

My gripe with this is - [email protected] is valid but [email protected] is not.
IMHO - This is vendor-specific behavior which should not be get invoked OOTB. It should be a configuration option.
And if it does, it should give a more specific message: Gmail usernames cannot be less than 6 digits.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jaxkodex picture jaxkodex  路  3Comments

IOAyman picture IOAyman  路  4Comments

malkhuzayyim picture malkhuzayyim  路  4Comments

karladler picture karladler  路  3Comments

galki picture galki  路  3Comments