[Django]-DRF SessionAuthentication login page insecurity?

3👍

Maybe it’s a bit strangely worded. This is related to django.contrib.auth.views. Within these there is a login() function and this login function is meant as Django’s standard login view.

How to log a user in part of documentation in Django describes how login() should be used.

To log a user in, from a view, use login(). It takes an HttpRequest object and a User object. login() saves the user’s ID in the session, using Django’s session framework.

There is also a login example code:

from django.contrib.auth import authenticate, login

def my_view(request):
    username = request.POST['username']
    password = request.POST['password']
    user = authenticate(request, username=username, password=password)
    if user is not None:
        login(request, user)
        # Redirect to a success page.
        ...
    else:
        # Return an 'invalid login' error message.
        ...

You can still implement your own login system, but in most cases you will still be using Django’s login() to actually log a user in. You can check login() source code here to see how it’s implemented.

👤Borut

3👍

I went down the rabbit hole, and here’s what I found out.

"Django’s standard login view"

There is actually a view called login in django.contrib.auth.views (source code). When used, it calls LoginView.as_view()(request), from the same module. This actually uses the login function from django.contrib.auth (imported as auth_login). Since LoginView is a Class Based View, its dispatch method will be called. Looking from the source, few layers of protection can be detected.

  1. django.views.decorators.debug.sensitive_post_parameters: When called without parameters, will hide any post parameters replacing them with stars (********). This allows sensitive information, such as the username and password, to be filtered out of reports when an error occurs .
  2. django.views.decorators.csrf.csrf_protect: Provides CSRF protection. For example, when using CSRF cookies, compares the csrftoken cookie to the a) Hidden CSRF input form field or b) X-CSRFTOKEN HTTP Request Header. This helps mitigating CSRF Login attacks.
  3. django.views.decorators.cache.never_cache: Add Cache-Control: max-age=0, no-cache, no-store, must-revalidate to the HTTP Response Header. I’m pretty sure this has also something to do with safety.

In addition, to the get_redirect_url method of the LoginView, there is comment Return the user-originating redirect URL if it's safe., so there is possibly yet another safety-layer, but I could not see how it makes the redirection URL "safe".

What I should take into account to make a view "as secure as the Django’s standard login view"?

Based on the layers of protection in the django.contrib.auth.views.LoginView, at least the following should be considered:

  1. Hiding sensitive post parameters (from error logs), using the sensitive_post_parameters -decorator.
  2. Login form CSRF protection
  3. Preventing caching of the HttpResponse of succesful login
  4. When redirecting after login, ensuring that the url is safe.

Leave a comment