From 9d2503b9e1ad415a107d8fe92d4654ebd4376e78 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Tue, 6 Oct 2020 11:58:49 +0200 Subject: [PATCH 2/2] validators: work around lack of NULL char check in forms.CharField (#46625) --- src/authentic2/__init__.py | 24 ++++++++++++++++++++++++ src/authentic2/validators.py | 26 ++++++++++++++++++++++++++ src/authentic2/views.py | 4 ++-- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/authentic2/__init__.py b/src/authentic2/__init__.py index c0ad2f29..89b69a0c 100644 --- a/src/authentic2/__init__.py +++ b/src/authentic2/__init__.py @@ -14,4 +14,28 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +import django + default_app_config = 'authentic2.apps.Authentic2Config' + + +if django.VERSION < (2,): + from . import validators + from django.forms import fields + import rest_framework.fields + + # query-string and form parameters used to query database charfield must be checked for NULL characters + # https://dev.entrouvert.org/issues/45672 + # https://dev.entrouvert.org/issues/46625 + # https://code.djangoproject.com/ticket/30064 + # https://github.com/django/django/commit/5b4c6b58a097028de970875605680df941ab0a47 + if not getattr(fields.CharField, 'a2_workaround', False): + CharField_old__init__ = fields.CharField.__init__ + + def CharField_new_init__(self, *args, **kwargs): + CharField_old__init__(self, *args, **kwargs) + self.validators.append(validators.ProhibitNullCharactersValidator()) + + fields.CharField.__init__ = CharField_new_init__ + fields.CharField.a2_workaround = True + rest_framework.fields.ProhibitNullCharactersValidator = validators.ProhibitNullCharactersValidator diff --git a/src/authentic2/validators.py b/src/authentic2/validators.py index 7311544b..0506a7bb 100644 --- a/src/authentic2/validators.py +++ b/src/authentic2/validators.py @@ -18,6 +18,8 @@ from __future__ import unicode_literals import smtplib +import django +from django.utils.deconstruct import deconstructible from django.utils.translation import ugettext_lazy as _ from django.core.exceptions import ValidationError from django.core.validators import RegexValidator, EmailValidator as DjangoEmailValidator @@ -97,3 +99,27 @@ class UsernameValidator(RegexValidator): def __init__(self, *args, **kwargs): self.regex = app_settings.A2_REGISTRATION_FORM_USERNAME_REGEX super(UsernameValidator, self).__init__(*args, **kwargs) + + +@deconstructible +class ProhibitNullCharactersValidator: + """Validate that the string doesn't contain the null character.""" + message = _('Null characters are not allowed.') + code = 'null_characters_not_allowed' + + def __init__(self, message=None, code=None): + if message is not None: + self.message = message + if code is not None: + self.code = code + + def __call__(self, value): + if '\x00' in str(value): + raise ValidationError(self.message, code=self.code) + + def __eq__(self, other): + return ( + isinstance(other, self.__class__) + and self.message == other.message + and self.code == other.code + ) diff --git a/src/authentic2/views.py b/src/authentic2/views.py index ec2b5063..6bbb4f8e 100644 --- a/src/authentic2/views.py +++ b/src/authentic2/views.py @@ -47,9 +47,9 @@ from django.contrib.auth import get_user_model from django.http import Http404 from django.utils.http import urlsafe_base64_decode from django.views.generic.edit import CreateView -from django.forms import CharField from django.http import HttpResponseBadRequest from django.template import loader +from django import forms from authentic2.custom_user.models import iter_attributes from . import (utils, app_settings, decorators, constants, @@ -991,7 +991,7 @@ class RegistrationCompletionView(CreateView): if 'username' in self.fields and app_settings.A2_REGISTRATION_FORM_USERNAME_REGEX: # Keep existing field label and help_text old_field = form_class.base_fields['username'] - field = CharField( + field = forms.CharField( max_length=256, label=old_field.label, help_text=old_field.help_text, -- 2.28.0