#29206: ValidationError when a reset password link contains a bad UIDB64 UUID ---------------------------------+------------------------------------ Reporter: Mattia Procopio | Owner: nobody Type: Bug | Status: new Component: contrib.auth | Version: 2.0 Severity: Normal | Resolution: Keywords: | Triage Stage: Accepted Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 ---------------------------------+------------------------------------ Changes (by Tim Graham):
* component: Uncategorized => contrib.auth * type: Uncategorized => Bug * stage: Unreviewed => Accepted Old description: > Our user model pk is a UUID, while making some tests trying to reset the > password, we met a 500 because the encoded UUID is not decoded properly. > Here's the URL: > http://127.0.0.1:8000/reset/MTgiYWRiYmItZWNhYi00OTBiLThiMTMtYzg0MDUxMWRmOTVl/4u3-853c9fe868a403fa439f/ > > and this is the traceback: > > {{{ > ValueError: invalid literal for int() with base 16: > '18"adbbbecab490b8b13c840511df95e' > File "django/db/models/fields/__init__.py", line 2363, in to_python > return uuid.UUID(value) > File "python3.6/uuid.py", line 141, in __init__ > int = int_(hex, 16) > > ValidationError: ['\'18"adbbb-ecab-490b-8b13-c840511df95e\' is not a > valid UUID.'] > File "django/core/handlers/exception.py", line 35, in inner > response = get_response(request) > File "django/core/handlers/base.py", line 128, in _get_response > response = self.process_exception_by_middleware(e, request) > File "django/core/handlers/base.py", line 126, in _get_response > response = wrapped_callback(request, *callback_args, > **callback_kwargs) > File "django/views/decorators/debug.py", line 76, in > sensitive_post_parameters_wrapper > return view(request, *args, **kwargs) > File "django/views/decorators/cache.py", line 44, in _wrapped_view_func > response = view_func(request, *args, **kwargs) > File "django/contrib/auth/views.py", line 329, in > password_reset_confirm > user = UserModel._default_manager.get(pk=uid) > File "django/db/models/manager.py", line 82, in manager_method > return getattr(self.get_queryset(), name)(*args, **kwargs) > File "django/db/models/query.py", line 397, in get > num = len(clone) > File "django/db/models/query.py", line 254, in __len__ > self._fetch_all() > File "django/db/models/query.py", line 1179, in _fetch_all > self._result_cache = list(self._iterable_class(self)) > File "django/db/models/query.py", line 53, in __iter__ > results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, > chunk_size=self.chunk_size) > File "django/db/models/sql/compiler.py", line 1051, in execute_sql > sql, params = self.as_sql() > File "django/db/models/sql/compiler.py", line 459, in as_sql > where, w_params = self.compile(self.where) if self.where is not None > else ("", []) > File "django/db/models/sql/compiler.py", line 391, in compile > sql, params = node.as_sql(self, self.connection) > File "django/db/models/sql/where.py", line 80, in as_sql > sql, params = compiler.compile(child) > File "django/db/models/sql/compiler.py", line 391, in compile > sql, params = node.as_sql(self, self.connection) > File "django/db/models/lookups.py", line 161, in as_sql > rhs_sql, rhs_params = self.process_rhs(compiler, connection) > File "django/db/models/lookups.py", line 260, in process_rhs > return super().process_rhs(compiler, connection) > File "django/db/models/lookups.py", line 93, in process_rhs > return self.get_db_prep_lookup(value, connection) > File "django/db/models/lookups.py", line 187, in get_db_prep_lookup > [get_db_prep_value(value, connection, prepared=True)] > File "django/db/models/fields/__init__.py", line 2354, in > get_db_prep_value > value = self.to_python(value) > File "django/db/models/fields/__init__.py", line 2368, in to_python > params={'value': value}, > }}} > > The error is raised when **user = > UserModel._default_manager.get(pk=uid)** is executd, while I think a > ValidationError is a proper exception I'm wondering if that couldn't be > catched within that try/except. I feel is a bit weird getting a 500 if > somebody tries to forge a URL for example. New description: Our user model pk is a UUID, while making some tests trying to reset the password, we met a 500 because the encoded UUID is not decoded properly. Here's the URL: http://127.0.0.1:8000/reset/MTgiYWRiYmItZWNhYi00OTBiLThiMTMtYzg0MDUxMWRmOTVl/4u3-853c9fe868a403fa439f/ and this is the traceback: {{{ ValueError: invalid literal for int() with base 16: '18"adbbbecab490b8b13c840511df95e' File "django/db/models/fields/__init__.py", line 2363, in to_python return uuid.UUID(value) File "python3.6/uuid.py", line 141, in __init__ int = int_(hex, 16) ValidationError: ['\'18"adbbb-ecab-490b-8b13-c840511df95e\' is not a valid UUID.'] File "django/core/handlers/exception.py", line 35, in inner response = get_response(request) File "django/core/handlers/base.py", line 128, in _get_response response = self.process_exception_by_middleware(e, request) File "django/core/handlers/base.py", line 126, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "django/views/decorators/debug.py", line 76, in sensitive_post_parameters_wrapper return view(request, *args, **kwargs) File "django/views/decorators/cache.py", line 44, in _wrapped_view_func response = view_func(request, *args, **kwargs) File "django/contrib/auth/views.py", line 329, in password_reset_confirm user = UserModel._default_manager.get(pk=uid) File "django/db/models/manager.py", line 82, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "django/db/models/query.py", line 397, in get num = len(clone) File "django/db/models/query.py", line 254, in __len__ self._fetch_all() File "django/db/models/query.py", line 1179, in _fetch_all self._result_cache = list(self._iterable_class(self)) File "django/db/models/query.py", line 53, in __iter__ results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size) File "django/db/models/sql/compiler.py", line 1051, in execute_sql sql, params = self.as_sql() File "django/db/models/sql/compiler.py", line 459, in as_sql where, w_params = self.compile(self.where) if self.where is not None else ("", []) File "django/db/models/sql/compiler.py", line 391, in compile sql, params = node.as_sql(self, self.connection) File "django/db/models/sql/where.py", line 80, in as_sql sql, params = compiler.compile(child) File "django/db/models/sql/compiler.py", line 391, in compile sql, params = node.as_sql(self, self.connection) File "django/db/models/lookups.py", line 161, in as_sql rhs_sql, rhs_params = self.process_rhs(compiler, connection) File "django/db/models/lookups.py", line 260, in process_rhs return super().process_rhs(compiler, connection) File "django/db/models/lookups.py", line 93, in process_rhs return self.get_db_prep_lookup(value, connection) File "django/db/models/lookups.py", line 187, in get_db_prep_lookup [get_db_prep_value(value, connection, prepared=True)] File "django/db/models/fields/__init__.py", line 2354, in get_db_prep_value value = self.to_python(value) File "django/db/models/fields/__init__.py", line 2368, in to_python params={'value': value}, }}} The error is raised when `user = UserModel._default_manager.get(pk=uid)` is executed, while I think a ValidationError is a proper exception I'm wondering if that couldn't be catched within that try/except. I feel is a bit weird getting a 500 if somebody tries to forge a URL for example. -- Comment: Yes, that shouldn't generate an exception. -- Ticket URL: <https://code.djangoproject.com/ticket/29206#comment:1> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/069.2252df0ec746d3ea7ef576e3a4ea905e%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.