diff --git a/src/pretix/base/middleware.py b/src/pretix/base/middleware.py index 677816723d..c7ab50166c 100644 --- a/src/pretix/base/middleware.py +++ b/src/pretix/base/middleware.py @@ -24,6 +24,7 @@ from urllib.parse import urlparse, urlsplit from zoneinfo import ZoneInfo, ZoneInfoNotFoundError from django.conf import settings +from django.core.exceptions import BadRequest from django.http import Http404, HttpRequest, HttpResponse from django.middleware.common import CommonMiddleware from django.urls import get_script_prefix, resolve @@ -347,6 +348,18 @@ class SecurityMiddleware(MiddlewareMixin): return resp +class RejectInvalidInputMiddleware(MiddlewareMixin): + + def process_request(self, request): + # Nullbytes in GET/POST parameters are mostly harmless, as they will later fail on database insertion, but it + # keeps spamming our error logs whenever someone tries to run a vulnerability scanner. + if "\x00" in request.META['QUERY_STRING'] or "%00" in request.META['QUERY_STRING']: + raise BadRequest("Invalid characters in input.") + if request.method in ('POST', 'PUT', 'PATCH') and request.content_type == "application/x-www-form-urlencoded": + if any("\x00" in value for key, value_list in request.POST.lists() for value in value_list): + raise BadRequest("Invalid characters in input.") + + class CustomCommonMiddleware(CommonMiddleware): def get_full_path_with_slash(self, request): diff --git a/src/pretix/settings.py b/src/pretix/settings.py index a798c55d33..aa86977963 100644 --- a/src/pretix/settings.py +++ b/src/pretix/settings.py @@ -515,6 +515,7 @@ MIDDLEWARE = [ 'pretix.control.middleware.AuditLogMiddleware', 'pretix.base.middleware.LocaleMiddleware', 'pretix.base.middleware.SecurityMiddleware', + 'pretix.base.middleware.RejectInvalidInputMiddleware', 'pretix.presale.middleware.EventMiddleware', 'pretix.api.middleware.ApiScopeMiddleware', ]