diff --git a/inyoka/middlewares/common.py b/inyoka/middlewares/common.py index a10d9823c..4e183b209 100644 --- a/inyoka/middlewares/common.py +++ b/inyoka/middlewares/common.py @@ -16,6 +16,7 @@ """ from django.conf import settings from django.contrib import messages +from django.http import HttpResponse from django.middleware.common import CommonMiddleware from django_hosts.middleware import HostsRequestMiddleware @@ -35,7 +36,13 @@ def process_request(self, request): request.watch = StopWatch() request.watch.start() - # IMPORTANT: Since we run some setupcode (mainly locals), this middleware + # reject URLs with NUL byte. + # If those are passed to the ORM with postgres, an exception is raised + # It's also mentioned in https://datatracker.ietf.org/doc/html/rfc3986#section-7.3 + if '\x00' in request.path: + return HttpResponse(content='The URL contained NUL characters', status=400, content_type='text/plain') + + # IMPORTANT: Since we run some setup-code (mainly locals), this middleware # needs to be the first one, hence we manually dispatch to HostsMiddleware response = HostsRequestMiddleware.process_request(self, request) if response is not None: diff --git a/tests/utils/test_middleware.py b/tests/utils/test_middleware.py new file mode 100644 index 000000000..7b24c515d --- /dev/null +++ b/tests/utils/test_middleware.py @@ -0,0 +1,27 @@ +""" + tests.apps.utils.test_middleware + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Test Inyoka-custom middlewares. + + :copyright: (c) 2012-2023 by the Inyoka Team, see AUTHORS for more details. + :license: BSD, see LICENSE for more details. +""" +from django.conf import settings + +from inyoka.utils.test import InyokaClient, TestCase + + +class TestNULByte(TestCase): + + client_class = InyokaClient + + def test_get_null(self): + url = f'http://{ settings.BASE_DOMAIN_NAME }/1%00%EF/' + response = self.client.get(url) + self.assertEqual(response.status_code, 400) + + def test_get_null_calender(self): + url = f'http://{ settings.BASE_DOMAIN_NAME }/2023/11/18/lpd-2023-10\x00EF2522/ics/' + response = self.client.get(url) + self.assertEqual(response.status_code, 400)