Opened 11 months ago

Closed 11 months ago

Last modified 11 months ago

#36711 closed New feature (wontfix)

Make createsuperuser in non-interactive mode observe AUTH_PASSWORD_VALIDATORS

Reported by: stan shaw Owned by: stan shaw
Component: contrib.auth Version: 5.2
Severity: Normal Keywords:
Cc: stan shaw, Markus Holtermann, Hasan Ramezani Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Component: django.contrib.auth

Description

The createsuperuser management command behaves inconsistently when running in interactive mode versus non-interactive mode (--noinput).

Interactive Mode: When run interactively, the command correctly prompts for a password and validates it against the AUTH_PASSWORD_VALIDATORS defined in settings.py.

Non-Interactive Mode: When run with --noinput, the command pulls the password from the DJANGO_SUPERUSER_PASSWORD environment variable. However, it fails to run this password through the validators. It passes the password directly to the create_superuser method.

This allows a weak, non-compliant password to be set in automated environments (like CI/CD pipelines, Dockerfiles, or deployment scripts), completely bypassing the project's configured password security policy.

How to Reproduce

Configure Validators: In your project's settings.py, add a strict password validator:

AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {
'min_length': 20, # Set a long minimum length
}
},
]

Apply Migrations: Ensure the database is set up.

python manage.py migrate

Test Interactive Mode (Works Correctly):
Run the command interactively and try to enter a short password.

$ python manage.py createsuperuser
Username: testuser
Email address: test@example.com
Password: 123
Password (again): 123
This password is too short. It must contain at least 20 characters.
Bypass password validation and create user anyway? [y/N]:
...

This fails as expected.

Test Non-Interactive Mode (The Bug):
Set the environment variable to the same short, invalid password and run with --noinput.

export DJANGO_SUPERUSER_PASSWORD="123"
python manage.py createsuperuser --noinput --username admin --email admin@example.com

Expected Result

The command should fail with a CommandError stating, "This password is too short."

Actual Result

The command succeeds, and the superuser is created with the non-compliant password "123".

Superuser created successfully.

Change History (4)

comment:1 by Jacob Walls, 11 months ago

Cc: Markus Holtermann Hasan Ramezani added
Version 0, edited 11 months ago by Jacob Walls (next)

comment:2 by stan shaw, 11 months ago

I've opened a Pull Request for this ticket on GitHub here: ​https://github.com/django/django/pull/20062/commits/

This PR includes the necessary fix and corresponding tests, and is now ready for review.

comment:3 by stan shaw, 11 months ago

Has patch: set

comment:4 by Jacob Walls, 11 months ago

Resolution: → wontfix
Status: assigned → closed
Summary: createsuperuser in non-interactive mode bypasses AUTH_PASSWORD_VALIDATORS → Make createsuperuser in non-interactive mode observe AUTH_PASSWORD_VALIDATORS
Type: Bug → New feature

Password validation in createsuperuser was ​discussed at length on the old mailing list.

I grant that there's an inconsistency here given that the other variables are cleaned:

DJANGO_SUPERUSER_EMAIL=garbage ./manage.py createsuperuser --no-input --username jane
CommandError: Enter a valid email address.

... but I don't think validating this password takes account of the fact that createsuperuser is a convenience for an administrator who's tasked with choosing a secure password and can set it themselves in a shell, as opposed to setting a password policy for users.

This would be a breaking change, see the ​overwhelming usage of this feature to set dummy passwords for development.

Requiring dummy development passwords to be strong could even nudge users into a false sense of security, by encouraging reuse of a password committed to version control in production because it "looks secure", as mentioned ​here.

I'll close as wontfix according to our triage process, but feel free to pursue this further on the Django forum to see what others think.


I'd be open to a PR logging a warning (as Refs #36711 --), in the spirit of Carl's advice that led to the interactive prompt to bypass validation from #28571:

So it's good to remind them of the validation fail, but there's no reason to make their life difficult.

Last edited 11 months ago by Jacob Walls (previous) (diff)
Note: See TracTickets for help on using tickets.
Back to Top