]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Security: disallow API remote-user auth if disabled (#6739)
authorshamoon <4887959+shamoon@users.noreply.github.com>
Wed, 15 May 2024 20:18:50 +0000 (13:18 -0700)
committerGitHub <noreply@github.com>
Wed, 15 May 2024 20:18:50 +0000 (20:18 +0000)
src/paperless/auth.py
src/paperless/tests/test_remote_user.py

index ba9320b5dab9b8cf08f4d3de46f06b2930a3e376..6ca97d608141aeef8b743d25bb2f22fd79b40348 100644 (file)
@@ -52,6 +52,17 @@ class HttpRemoteUserMiddleware(PersistentRemoteUserMiddleware):
 
     header = settings.HTTP_REMOTE_USER_HEADER_NAME
 
+    def process_request(self, request: HttpRequest) -> None:
+        # If remote user auth is enabled only for the frontend, not the API,
+        # then we need dont want to authenticate the user for API requests.
+        if (
+            "/api/" in request.path
+            and "paperless.auth.PaperlessRemoteUserAuthentication"
+            not in settings.REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"]
+        ):
+            return
+        return super().process_request(request)
+
 
 class PaperlessRemoteUserAuthentication(authentication.RemoteUserAuthentication):
     """
index c5d7a6db484562397cd384d1a94e84281d0fb299..ebe1b3ff5d3e125c8dbe913b2eed1db0895c0754 100644 (file)
@@ -2,6 +2,7 @@ import os
 from unittest import mock
 
 from django.contrib.auth.models import User
+from django.test import override_settings
 from rest_framework import status
 from rest_framework.test import APITestCase
 
@@ -88,6 +89,38 @@ class TestRemoteUser(DirectoriesMixin, APITestCase):
 
             self.assertEqual(response.status_code, status.HTTP_200_OK)
 
+    @override_settings(
+        REST_FRAMEWORK={
+            "DEFAULT_AUTHENTICATION_CLASSES": [
+                "rest_framework.authentication.BasicAuthentication",
+                "rest_framework.authentication.TokenAuthentication",
+                "rest_framework.authentication.SessionAuthentication",
+            ],
+        },
+    )
+    def test_remote_user_api_disabled(self):
+        """
+        GIVEN:
+            - Configured user
+            - Remote user auth enabled for frontend but disabled for the API
+            - Note that REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'] is set in settings.py in production
+        WHEN:
+            - API call is made to get documents
+        THEN:
+            - Call fails
+        """
+        response = self.client.get(
+            "/api/documents/",
+            headers={
+                "Remote-User": self.user.username,
+            },
+        )
+
+        self.assertIn(
+            response.status_code,
+            [status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN],
+        )
+
     def test_remote_user_header_setting(self):
         """
         GIVEN: