From e20acfa5a9b05ae9ab8d2eb6ae0102bede33d934 Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Tue, 4 Mar 2025 23:40:33 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=EF=B8=8F(backend)=20limit=20user?= =?UTF-8?q?=20listing=20endpoint=20with=20security=20flag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deactivate inherited user listing capability that allows authenticated users to retrieve all application users in JSON format. This potentially unsecure endpoint exposes user database to scraping and isn't currently used in the application. Implement security flag to disable access until properly refactored for upcoming invitation feature. Will revisit and adapt endpoint behavior when developing user invitation functionality. --- src/backend/core/api/viewsets.py | 5 ++-- src/backend/core/tests/test_api_users.py | 29 +++++++++++++++++++++--- src/backend/meet/settings.py | 3 +++ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py index a7ebbc4d..245300ce 100644 --- a/src/backend/core/api/viewsets.py +++ b/src/backend/core/api/viewsets.py @@ -150,9 +150,8 @@ class UserViewSet( queryset = self.queryset if self.action == "list": - # Exclude all users already in the given document - if document_id := self.request.GET.get("document_id", ""): - queryset = queryset.exclude(documentaccess__document_id=document_id) + if not settings.ALLOW_UNSECURE_USER_LISTING: + return models.User.objects.none() # Filter users by email similarity if query := self.request.GET.get("q", ""): diff --git a/src/backend/core/tests/test_api_users.py b/src/backend/core/tests/test_api_users.py index a8f182ad..10374fb8 100644 --- a/src/backend/core/tests/test_api_users.py +++ b/src/backend/core/tests/test_api_users.py @@ -22,10 +22,32 @@ def test_api_users_list_anonymous(): } -def test_api_users_list_authenticated(): +def test_api_users_list_authenticated_secure(settings): """ - Authenticated users should be able to list users. + Authenticated users should not be able to list any user + when ALLOW_UNSECURE_USER_LISTING is False. """ + settings.ALLOW_UNSECURE_USER_LISTING = False + user = factories.UserFactory() + + client = APIClient() + client.force_login(user) + + factories.UserFactory.create_batch(2) + response = client.get( + "/api/v1.0/users/", + ) + assert response.status_code == 200 + content = response.json() + assert len(content["results"]) == 0 + + +def test_api_users_list_authenticated_unsecure(settings): + """ + Authenticated users should be able to list all users + when ALLOW_UNSECURE_USER_LISTING is True. + """ + settings.ALLOW_UNSECURE_USER_LISTING = True user = factories.UserFactory() client = APIClient() @@ -40,11 +62,12 @@ def test_api_users_list_authenticated(): assert len(content["results"]) == 3 -def test_api_users_list_query_email(): +def test_api_users_list_query_email(settings): """ Authenticated users should be able to list users and filter by email. """ + settings.ALLOW_UNSECURE_USER_LISTING = True user = factories.UserFactory() client = APIClient() diff --git a/src/backend/meet/settings.py b/src/backend/meet/settings.py index f86eddf2..907cf34b 100755 --- a/src/backend/meet/settings.py +++ b/src/backend/meet/settings.py @@ -73,6 +73,9 @@ class Base(Configuration): ALLOWED_HOSTS = values.ListValue([]) SECRET_KEY = values.Value(None) SILENCED_SYSTEM_CHECKS = values.ListValue([]) + ALLOW_UNSECURE_USER_LISTING = values.BooleanValue( + False, environ_name="ALLOW_UNSECURE_USER_LISTING", environ_prefix=None + ) # Application definition ROOT_URLCONF = "meet.urls"