Django 1.9" Common Password Validator" - 奇怪的行为

时间:2016-03-23 18:08:55

标签: django python-3.x passwords change-password django-1.9

我试图用我自己的相同版本替换内置common-passwords.txt.gz文件,该文件应该包含前1000个常用密码,其中包含我国家的前10,000个常用密码,但我&#39 ;我遇到了一些相当奇怪的行为。

  1. 首先,我直接用我自己的.txt文件替换Django' common-passwords.txt.gz文件(4KB),其中包含与Django相同的utf-8编码(以34KB的速度提供),然后重启测试服务器。将用户密码更改为"密码"它不像Django的常用密码文件那样引起预期的错误。

    内置密码列表和我的新密码列表的第一行从123456password12345678qwerty123456789...开始,所以它显然应该这样做。

    当我在他们的公共密码文件中添加一些额外的密码时,它看起来应该正常工作并且如果我尝试将它们用作密码则会引发错误,所以我不认为它是这样的缓存在某处或类似的地方。

    公共密码列表或gzip.open(password_list_path).read().decode('utf-8').splitlines()功能是否存在某种内置文件大小限制?

  2. 其次,试图找出上述内容让我陷入了一个奇怪的错误。使用内置在common-passwords.txt.gz中的Django(第一行开始123456password12345678qwerty123456789...)成功地为"密码"提出了验证错误。和"密码1",但不是"密码12"或"密码123"!

    当我读到它时,Django验证代码基本上检查提交的密码is in是否来自公共密码文件的每一行,并且我找不到任何代码来免除验证之后一定长度的密码。我错过了什么或者这是一个错误吗?

  3. "通用密码验证" Django 1.9中的函数可以在\venv\Lib\site-packages\django\contrib\auth\password_validation.py找到,相关的类如下:

    class CommonPasswordValidator(object):
    """
    Validate whether the password is a common password.
    
    The password is rejected if it occurs in a provided list, which may be gzipped.
    The list Django ships with contains 1000 common passwords, created by Mark Burnett:
    https://xato.net/passwords/more-top-worst-passwords/
    """
        DEFAULT_PASSWORD_LIST_PATH = os.path.join(
            os.path.dirname(os.path.realpath(upath(__file__))), 'common-passwords.txt.gz'
        )
    
        def __init__(self, password_list_path=DEFAULT_PASSWORD_LIST_PATH):
            try:
                common_passwords_lines = gzip.open(password_list_path).read().decode('utf-8').splitlines()
            except IOError:
                with open(password_list_path) as f:
                    common_passwords_lines = f.readlines()
    
            self.passwords = {p.strip() for p in common_passwords_lines}
    
        def validate(self, password, user=None):
            if password.lower().strip() in self.passwords:
                raise ValidationError(
                    _("This password is too common (it would be trivial to crack!)"),
                    code='password_too_common',
                )
    
        def get_help_text(self):
            return _("Your password can't be a commonly used password.")
    

1 个答案:

答案 0 :(得分:1)

终于到了最底层!

Django内置的通用密码验证文件中包含的密码之间存在某种不可见的未渲染字符,这解释了我遇到的两个问题。

我改变了我的前10k普通密码文件,在它们之间有通常的换行符,现在一切都很好!即使现在有10倍的密码可供它进行比较,它仍然可以立即运行!

我已将10,000个最常见的密码文件上传到github,以供将来遇到此问题或只想改进Django内置常用密码验证的人员使用:https://github.com/timboss/Django-Common-Password-Validation/