misc: check URL given as return after picking a file (#63460)
gitea/fargo/pipeline/head Build started... Details

This commit is contained in:
Frédéric Péters 2022-04-01 15:31:09 +02:00
parent 36cb2480c8
commit 6662653560
2 changed files with 24 additions and 0 deletions

View File

@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
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)

View File

@ -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('/')