New Password Validators

156 views
Skip to first unread message

Mehmet Dogan

unread,
Aug 30, 2018, 11:17:28 PM8/30/18
to Django developers (Contributions to Django itself)
Hi Everybody,

Django currently ships with the following password validators:

UserAttributeSimilarityValidator
MinimumLengthValidator
CommonPasswordValidator
NumericPasswordValidator

However, it is typical nowadays to require uppercase, lowercase, at least a numeric character and a non-alphanumeric character, or a symbol. 

Is there any reason, why these not included in Django? I assume most serious Django applications use them. A sample implementation:

class HasLowerCaseValidator:
def __init__(self):
self.message = "The password must contain at least one lowercase character."

def validate(self, password, user=None):
if re.search('[a-z]', password) is None:
raise ValidationError(
self.message,
code='missing_lower_case',
)

def get_help_text(self):
return self.message


class HasUpperCaseValidator:
def __init__(self):
self.message = "The password must contain at least one uppercase character."

def validate(self, password, user=None):
if re.search('[A-Z]', password) is None:
raise ValidationError(
self.message,
code='missing_upper_case',
)

def get_help_text(self):
return self.message


class HasNumberValidator:
def __init__(self):
self.message = "The password must contain at least one numeric character."

def validate(self, password, user=None):
if re.search('[0-9]', password) is None:
raise ValidationError(
self.message,
code='missing_numeric',
)

def get_help_text(self):
return self.message


class HasSymbolValidator:
def __init__(self):
self.message = "The password must contain at least one non-alphanumeric character (symbol)."

def validate(self, password, user=None):
if re.search('[^A-Za-z0-9]', password) is None:
raise ValidationError(
self.message,
code='missing_symbol',
)

def get_help_text(self):
return self.message

Regards,

Mehmet 

James Bennett

unread,
Aug 30, 2018, 11:32:58 PM8/30/18
to django-d...@googlegroups.com
This type of enforced "complexity" does not increase security, and relevant standards groups now recommend not trying to enforce these rules.

Quoting US NIST 800-63B, Appendix A:

> As noted above, composition rules are commonly used in an attempt to increase the difficulty of guessing user-chosen passwords. Research has shown, however, that users respond in very predictable ways to the requirements imposed by composition rules [Policies]. For example, a user that might have chosen “password” as their password would be relatively likely to choose “Password1” if required to include an uppercase letter and a number, or “Password1!” if a symbol is also required.

The NIST guidelines now say (800-63B §5.1.1.1):

> Memorized secrets SHALL be at least 8 characters in length if chosen by the subscriber. Memorized secrets chosen randomly by the CSP or verifier SHALL be at least 6 characters in length and MAY be entirely numeric. If the CSP or verifier disallows a chosen memorized secret based on its appearance on a blacklist of compromised values, the subscriber SHALL be required to choose a different memorized secret. No other complexity requirements for memorized secrets SHOULD be imposed.

I would be against adding validators to Django to try to enforce these deprecated practices.

Adam Johnson

unread,
Aug 31, 2018, 3:23:13 AM8/31/18
to django-d...@googlegroups.com
I agree with James, Django core shouldn't include these. If your organization requires you to implement such practices despite their problems, add your own password validators, and maybe distribute them in a third party package!

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAL13Cg_%2BKMi2naSExPR0MVvBb0JnY%3DFV7A6goDHeaTWRoSpaJQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


--
Adam

Anand Mishra

unread,
Aug 31, 2018, 7:36:03 AM8/31/18
to django-d...@googlegroups.com
I agree with James and Adams, password validation rules depend on business and should not be forced by core onto developers


For more options, visit https://groups.google.com/d/optout.


This message contains confidential information and is intended only for the individual named. If you are not the name addressee you should not disseminate, distribute or copy this e-mail. You cannot use or forward any attachments in the email. Please notify the sender immediately by e-mail if you have received this e-mail by mistake and delete this e-mail from your system. Analytics Vidhya Educon Private Limited, DLF Phase 2, Gurgaon, India, www.analyticsvidhya.com

Mehmet Dogan

unread,
Aug 31, 2018, 2:00:02 PM8/31/18
to django-d...@googlegroups.com

Hey James,

 

Thank you for the resources you provided. I really learned a lot. Here are a few points (references/details at the very bottom):

 

  1. Blacklisting: Seems to be most effective, I agree. However, Django does not seem to be up to date on this either. The list of 1000 most common password it uses seem to be taken from an URL which is not available anymore, and the page it redirects to is dated 2011! So the list is at least around 10 years old, and it does not catch all of top 25 words listed on Wikipedia. Samples of passwords it allows: qwertyuiop, 987654321, 1234567890, abcdefgh

 

  1. Are Complexity Requirements Deprecated?: I checked changing my password for 3 major tech companies: Gmail, Microsoft account, and for my Apple Id. Only Gmail did not require password complexity. So, most do require password complexity although they do have 2-factor authentication in place. Most Django deployments, more than 95% I assume, would not have 2-factor authentication, so password complexity is more needed.

 

  1. Do Complexity Requirements Work?:
    1. Research: From the resources you linked, I read one article (ref’ed below). Here are key findings:

                                                              i.      A complex 8-character password had entropy of 34.3 where as a basic 8-character one had 29.43 (calculated with the specific method mentioned in the article). Not a huge difference, however not too bad either, that is about 17% gain.

                                                             ii.      188/972 (=20%) of the basic-8 passwords was cracked (with the tool mentioned in the article), whereas this number is 0 (zero) for the complex-8 group. A big difference there.

                                                           iii.      About 15% of the basic group wrote down their passwords, either electronically or paper and pencil, where as this number is about 27% for the complex. Simpler passwords is the winner here, however one should not forget, written passwords are expected have their own protection (of some sort). Another thing to consider is that, if one is targeted individually, a written password might be a big vulnerability; however, for general account/password screenings this may not be as bad.

All in all, I say, password complexity has benefits; although not as much as one would expect.

    1. Complexity and Blacklisting Can Interoperate: For the simple case of “Password1!” mentioned below, the best method to tackle, I think, would be 1) remove the numbers and characters at the end 2) lowercase the first character 3) lookup in the black list. In other words, tackle the thinking pattern algorithmically, not by listing cases in a text file. 

    2. Complexity support blacklisting: Check this list of common passwords, for example: https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/500-worst-passwords.txt (provided by the Author of the Django’s list of common passwords). Most items there are either all lowercase or all numbers etc. By just requiring 1 upper case character, one could know off 60% off them. Adding a number, and a symbol requirement would easily bring that up to 95%.. Sure, those who are committed to not password protecting their accounts would find something in the remaining 5% (as in the example of “Password1!”), howerver, policies would be made for the mainstream, not for the extremes.

 

Bottom line; I think password complexity do have some benefits, and inclusion in Django would provide options, and save time to those who would like to use them. Regards,

 

Mehmet

 

 

 

 

 

References/Details:

 

  1. URL referenced in Django for the list of 1000 most common passwords : https://xato.net/passwords/more-top-worst-passwords/
    (location: django\contrib\auth\password_validation.py)
    Wikipedia: https://en.wikipedia.org/wiki/List_of_the_most_common_passwords

  2. G-Mail: Use at least 8 characters. Don’t use a password from another site, or something too obvious like your pet’s name.
    Microsoft Account: Strong passwords contain at least 8 characters, do not include common words or names, and combine uppercase letters, lowercase letters, numbers, and symbols.
    Apple Id: Your password must have: i) 8 or more characters ii) Upper & lowercase letters iii) At least one number

  3. a) Article: Of Passwords and People: Measuring the Effect of Password-Composition Policies (https://www.archive.ece.cmu.edu/~lbauer/papers/2011/chi2011-passwords.pdf). I picked this article since its name suggested it is very related to our topic, and that CMU is a reputable university.

--
You received this message because you are subscribed to a topic in the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-developers/Xlovt28QIDo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-develop...@googlegroups.com.

Mehmet Dogan

unread,
Aug 31, 2018, 2:08:00 PM8/31/18
to django-d...@googlegroups.com

2 points I forgot to mention:

 

  1. I think it would be interesting to look at what other web frameworks are doing, e.g., Ruby on Rails
  2. If what I offered is not added, I think it makes more sense to remove similar ones (e.g., NumericPasswordValidator) from Django to make it self consistent.

 

Mehmet

Dan Davis

unread,
Aug 31, 2018, 5:50:15 PM8/31/18
to django-d...@googlegroups.com
Mehmet,

If you need such complexity validators, then they are easy to add as package.  I think the reason why Django doesn't include more is that many use Oauth2 or other corporate authentication to validate.
You can see how this is done in one case by looking at https://github.com/mingchen/django-cas-ng, which I use in my corporate environment.


In the modern world, do we really need the ModelBackend much?   I hope not.

You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.

To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.

James Bennett

unread,
Aug 31, 2018, 6:44:23 PM8/31/18
to django-d...@googlegroups.com
I'm agreeing with the other replies saying that if this is really needed, it can be done as a third-party module.

As much as possible, I want to have Django avoid promoting outdated security policies (and the fact that many places still use them doesn't mean they're current; it means they haven't caught up to the published best practices).

The numeric validator does make some sense because there are cases where you want an all-numeric credential, and where it's not bad practice to do that. So it can stay, but I wouldn't want to add validators that try to enforce false "complexity".

Scot Hacker

unread,
Sep 1, 2018, 9:38:14 PM9/1/18
to Django developers (Contributions to Django itself)
Rather than enforce an arbitrary set of password construction rules, I prefer systems that gauge password strength as an overall entropy score, then let  sites establish the minimum overall strength they require. How that strength is achieved is up to each user - uou can either go short and random, or long and memorable. Length trumps pretty much all other factors, especially if you disallow strings such as the user's own username, email, company name, etc.). Dropbox created a system like this called zxcvbn and open sourced it.  It was then ported to python. 


I use a "roll your own" solution on top of zxcvbn-python in some of my projects (in order to show dynamic strength meters in the UI as user types), but others have converted it to work as a Django password validator.


If Django were to bundle any additional validators, this or something like it would have my vote.

./s

Mehmet Dogan

unread,
Sep 2, 2018, 10:14:19 AM9/2/18
to django-d...@googlegroups.com

Scot,

 

This is nice, thank you for sharing. I think something like this + an up to date black list should be good enough.

 

Mehmet

 

From: Scot Hacker
Sent: Saturday, September 1, 2018 8:38 PM
To: Django developers (Contributions to Django itself)
Subject: Re: New Password Validators

 

Rather than enforce an arbitrary set of password construction rules, I prefer systems that gauge password strength as an overall entropy score, then let  sites establish the minimum overall strength they require. How that strength is achieved is up to each user - uou can either go short and random, or long and memorable. Length trumps pretty much all other factors, especially if you disallow strings such as the user's own username, email, company name, etc.). Dropbox created a system like this called zxcvbn and open sourced it.  It was then ported to python. 

--

You received this message because you are subscribed to a topic in the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-developers/Xlovt28QIDo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.

Reply all
Reply to author
Forward
0 new messages