Opened 7 months ago

Last modified 4 months ago

#28016 assigned Bug

Command createsuperuser does not validate username when using --username

Reported by: Ricardo S. A. Silva Owned by: Ricardo S. A. Silva
Component: contrib.auth Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

It is possible to create a new user with invalid characters on username by running createsuperuser with only --username parameter. The username validation is only executed when the --noinput parameter is used.

Example:

manage.py createsuperuser --username %invalid%username

The problem also occurs for fields on REQUIRED_FIELDS (e.g. email):

manage.py createsuperuser --username test --email invalid_email

This can be fixed by adding some validation:

--- a/django/contrib/auth/management/commands/createsuperuser.py
+++ b/django/contrib/auth/management/commands/createsuperuser.py
@@ -94,6 +94,24 @@ class Command(BaseCommand):
                 if hasattr(self.stdin, 'isatty') and not self.stdin.isatty():
                     raise NotRunningInTTYException("Not running in a TTY")

+                # Validate username provided by --username parameter
+                if username:
+                    try:
+                        self.UserModel._meta.get_field(self.UserModel.USERNAME_FIELD).clean(username, None)
+                    except exceptions.ValidationError as e:
+                        raise CommandError('; '.join(e.messages))
+
+                # Validate data inputted by --< field_name >
+                for field_name in self.UserModel.REQUIRED_FIELDS:
+                    try:
+                        if options[field_name]:
+                            field = self.UserModel._meta.get_field(field_name)
+                            user_data[field_name] = field.clean(options[field_name], None)
+                        else:
+                            user_data[field_name] = None
+                    except exceptions.ValidationError as e:
+                        raise CommandError('; '.join(e.messages))
+
                 # Get a username
                 verbose_field_name = self.username_field.verbose_name
                 while username is None:
@@ -122,7 +140,6 @@ class Command(BaseCommand):

                 for field_name in self.UserModel.REQUIRED_FIELDS:
                     field = self.UserModel._meta.get_field(field_name)
-                    user_data[field_name] = options[field_name]
                     while user_data[field_name] is None:
                         message = '%s%s: ' % (
                             capfirst(field.verbose_name),

Change History (10)

comment:1 Changed 7 months ago by Ricardo S. A. Silva

Owner: changed from Ricardo S. A. Silva to Ricardo S. A. Silva
Last edited 7 months ago by Tim Graham (previous) (diff)

comment:2 Changed 7 months ago by kapil garg

Component: UncategorizedCore (Management commands)
Triage Stage: UnreviewedAccepted

comment:3 Changed 7 months ago by kapil garg

Has patch: set
Needs tests: set

Can you also add tests for this ? Here should be the new test added

comment:4 Changed 7 months ago by Ricardo S. A. Silva

Sure. I'll make it.

comment:5 Changed 7 months ago by Ricardo S. A. Silva

Done. PR updated.

Last edited 7 months ago by Ricardo S. A. Silva (previous) (diff)

comment:6 Changed 7 months ago by Ricardo S. A. Silva

Needs tests: unset

comment:7 Changed 7 months ago by Ricardo S. A. Silva

PR updated: Added checks for fields with unique constraint.

comment:8 Changed 7 months ago by Markus Holtermann

This seems highly correlated to #28044 -- I feel like tackling #28044 instead and marking this issue as a duplicate is a better option.

comment:9 Changed 4 months ago by Tim Graham

Patch needs improvement: set

As Markus noted, the current PR seems to duplicate more code which doesn't seem ideal.

comment:10 Changed 4 months ago by Tim Graham

Component: Core (Management commands)contrib.auth
Note: See TracTickets for help on using tickets.
Back to Top