0

I have a middleware class that looks something like this:

class DogMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        return self.get_response(request)

    def process_view(self, request, view_func, view_args, view_kwargs):
        dog_id = view_kwargs.get("dog_id")
        if dog_id is not None:
            dog = Dog.objects.get(id=dog_id)
            request.dog = dog

I have a view that looks something like this:

class DogDetail(APIView):
    def get(self, request, dog_id, *args, **kwargs):
         return "some nice doggy info"

My permissions default to IsAuthenticated:

    "DEFAULT_PERMISSION_CLASSES": (
        "rest_framework.permissions.IsAuthenticated",
    ),

When I call the DogDetail view from a logged-out state, with a dog that doesn't exist, I get a 500 error, and a DoesNotExist exception. I infer from this that the middleware runs before the permissions.

My questions: Is this expected behavior? If not, what am I doing wrong?

If so, it is very un-ideal, because it would be very easy to leak data through middleware. In my example, it would be very easy for a un-authenticated user to determine which dog_id's existed. What is a good way to mitigate this? I guess I could check for authentication in the middleware, and pass unauthenticated requests through without getting the dog_id? That feels like I'm headed for a deep bug in the future where middleware runs properly, but the dog doesn't get attached to the request.

Thank you in advance!

user7097722
  • 65
  • 1
  • 1
  • 5
  • Yes, middleware run before DRF authentication. Since DRF works mostly on the view layer, auth happens in the view (This is what allows you to control authentication on a view level). – Abdul Aziz Barkat May 11 '22 at 17:40

0 Answers0