From 666265356044c5d22579446347792656c9ebc5ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Fri, 1 Apr 2022 15:31:09 +0200 Subject: [PATCH] misc: check URL given as return after picking a file (#63460) --- fargo/fargo/views.py | 9 +++++++++ tests/test_public.py | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/fargo/fargo/views.py b/fargo/fargo/views.py index d38df6d..90c8473 100644 --- a/fargo/fargo/views.py +++ b/fargo/fargo/views.py @@ -15,6 +15,7 @@ # along with this program. If not, see . import logging +import urllib.parse from copy import deepcopy from json import dumps @@ -141,6 +142,14 @@ class PickView: self.pick_url = request.GET.get('pick') if not self.pick_url: return HttpResponseBadRequest('missing pick parameter') + if hasattr(settings, 'KNOWN_SERVICES'): + url_netloc = urllib.parse.urlparse(self.pick_url).netloc + valid_netlocs = set() + for services in settings.KNOWN_SERVICES.values(): + for service in services.values(): + valid_netlocs.add(urllib.parse.urlparse(service.get('url')).netloc) + if url_netloc not in valid_netlocs: + return HttpResponseForbidden('invalid pick URL') return super().dispatch(request, *args, **kwargs) diff --git a/tests/test_public.py b/tests/test_public.py index ccfda96..5badd34 100644 --- a/tests/test_public.py +++ b/tests/test_public.py @@ -16,6 +16,7 @@ import pytest +from django.test import override_settings from django.urls import reverse from django.utils.six.moves.urllib import parse as urlparse from webtest import Upload @@ -101,6 +102,20 @@ def test_pick(app, private_settings, john_doe, user_doc): assert '?url=' in response['Location'] +@override_settings(KNOWN_SERVICES={'wcs': {'forms': {'url': 'http://example.org/'}}}) +def test_pick_url_check(app, private_settings, john_doe, user_doc): + login(app, user=john_doe) + resp = app.get('/') + resp.form['content'] = Upload('monfichier.txt', b'coin', 'text/plain') + resp = resp.form.submit().follow() + pk = UserDocument.objects.all().first().id + + app.get(reverse('list_to_pick') + '?pick=http://client.org/callback/', status=403) + app.get(reverse('list_to_pick') + '?pick=http://example.org/callback/', status=200) + app.post(reverse('pick', kwargs={'pk': pk}) + '?pick=http://client.org/callback/', status=403) + app.post(reverse('pick', kwargs={'pk': pk}) + '?pick=http://example.org/callback/', status=302) + + def test_delete(app, john_doe, jane_doe): login(app, user=john_doe) resp = app.get('/')