#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:2 by , 4 weeks 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 , 4 weeks ago
| Has patch: | set |
|---|
comment:4 by , 3 weeks 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.
cc'ing folks from #27801