【问题标题】:Django 1.9 "Common Password Validator" - Strange BehaviourDjango 1.9“通用密码验证器”——奇怪的行为
【发布时间】:2016-07-11 04:24:45
【问题描述】:

我正在尝试用我自己的相同版本替换内置的 common-passwords.txt.gz 文件,该文件应该包含前 1,000 个常用密码,其中包含我所在国家/地区的前 10,000 个常用密码,但我遇到了一些相当奇怪的行为。

  1. 首先,我直接将 Django 的 common-passwords.txt.gz 文件 (4KB) 替换为我自己的包含我的 .txt 文件,该文件具有与 Django 相同的 utf-8 编码(输入为 34KB),然后重新启动测试服务器。将用户密码更改为“密码”时,它不会像使用 Django 的通用密码文件那样引发预期的错误。

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

    当我将一些额外的密码附加到他们的通用密码文件时,它似乎可以正常工作,如果我尝试将它们用作密码,则会引发错误,所以我不认为它被缓存在某处或类似的地方.

    通用密码列表或gzip.open(password_list_path).read().decode('utf-8').splitlines() 函数是否有某种内置文件大小限制?

  2. 其次,试图弄清楚上述问题导致我遇到了一个奇怪的错误。使用 Django 内置的 common-passwords.txt.gz(其中第一行以 123456password12345678qwerty123456789... 开头)成功引发了“password”和“password1”的验证错误,但“password12”或“password123”却没有!

    当我阅读它时,Django 验证代码基本上检查提交的密码is in 是否来自通用密码文件的每一行,并且我找不到任何代码可以免除超过一定长度的密码的验证。我错过了什么还是这是一个错误?

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.")

【问题讨论】:

  • 我认为通过覆盖来替换文件不是一个好主意。下面是一个如何将验证器与您的自定义路径 github.com/orcasgit/django-password-validation/blob/master/… 一起使用的示例。您能否提供更多关于您将在何处使用验证器的背景信息?
  • 我正在尝试在人们可以在我的应用程序中创建密码的任何地方使用验证器(目前只有管理界面,但最终也可以在自定义表单上!),这就是我尝试的原因直接用我自己的替换内置列表。如果出现 Password12 或 Password123 错误,您可以使用您的 Django 版本进行测试吗?

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


【解决方案1】:

终于搞定了!

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

我更改了我的前 10k 常用密码文件,改为在它们之间添加通常的换行符,现在一切正常!即使现在有 10 倍的密码可以与之比较,它仍然几乎可以立即运行!

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

【讨论】:

    猜你喜欢
    • 2021-11-09
    • 2016-05-21
    • 1970-01-01
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多