CVE-2024-35184 (published 2024-05-15T22:15Z)

Paperless-ngx is a document management system that transforms physical documents into a searchable online archive. Starting in version 2.5.0 and prior to version 2.8.6, remote user authentication allows API access even if API access is explicitly disabled. Version 2.8.6 contains a patchc for the issue.


Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/paperless-ngx/paperless-ngx
commit_details: repo_url: https://github.com/paperless-ngx/paperless-ngx
author: shamoon
author_date: 2024-05-15 13:18:50-07:00
msg: Security: disallow API remote-user auth if disabled (#6739)
repository: repo_url: https://github.com/paperless-ngx/paperless-ngx
repo_name: paperless-ngx/paperless-ngx
description: A community-supported supercharged version of paperless: scan, index and archive all your physical documents
repo_language: Python
owner: paperless-ngx
file_changes: filename: auth.py
change_type: ModificationType.MODIFY
diff: @@ -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):
     """

programming_language: Python
filename: test_remote_user.py
change_type: ModificationType.MODIFY
diff: @@ -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:

programming_language: Python