Code

Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#15518 closed New feature (fixed)

Separate CSRF checks to function

Reported by: vzima Owned by: nobody
Component: Documentation Version: 1.2
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

I have troubles with enabling CSRF check in some of my views because there is no function that would return True/False or raised an exception.

My situation is like this:
I have 2 views, one that is protected by CSRF and other one is not. Both views calls same rendering function which renders a form that leads to protected view.
Problem is when first request ends at unprotected view, I have no CSRF_COOKIE in request.META and csrf_token template tag did not rendered one, so rendering returns a form that will always return CSRF reject page.

Attachments (0)

Change History (8)

comment:1 Changed 3 years ago by anonymous

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

It's not at all clear to me what you are asking for here. I suspect the root of the problem is a misunderstanding about how to use the CSRF protection, as it's perfectly possible to have some views that are CSRF protected and others that are not. I suggest you ask on #django IRC or post a more complete description of your code to django-users for help.

comment:2 Changed 3 years ago by lukeplant

  • Resolution invalid deleted
  • Status changed from closed to reopened

I understand the problem, and it is a valid ticket. There is already a solution - django.views.decorators.csrf.requires_csrf_token

However, this function is not documented, and therefore 'doesn't exist yet'. Once documented, I'll close this ticket.

comment:3 Changed 3 years ago by lukeplant

  • Component changed from Core framework to Documentation
  • Triage Stage changed from Unreviewed to Accepted

comment:4 Changed 3 years ago by vzima

That is what I needed, but still there is no common way how to call CSRF check, if you want to do it manually.

Code for view with CSRF check not provided by middleware/decorator looks

from django.middleware.csrf import CsrfViewMiddleware, _get_new_csrf_key, _sanitize_token
from django.views.decorators.csrf import csrf_view_exempt

@csrf_view_exempt
def some_view(request):
    if (...some_conditions...):
        result = CsrfViewMiddleware().process_view(request, lambda: None, None, None)
        # if None is returned, than it is OK
        if result:
            # Store data back to session to prevent their loss
            return result
    return ...some other response...

We have view like this at endpoint for OpenID provider, but I do not like the way I have to call CSRF check.

comment:5 Changed 3 years ago by lukeplant

An alternative way to do this is to split your view function into several views, or into a closures, and decorate with @csrf_protect:

@csrf_view_exempt
def some_view(request):

    # Any setup here, including vars that may be referenced in path_1 or path_2

    @requires_csrf_token
    def path_1(request):
        # ...

    @csrf_protect
    def path_2(request):
        # ...

    if (...some_condition...):
        return path_1(request)
    else:
        return path_2(request)

This seems like a reasonable solution to me, especially for something which is very definitely an edge case. If you have things that you need to do instead of immediately returning the 403 failure view, you can:

  • subclass CsrfViewMiddleware
  • override the _reject method
  • make your own version of csrf_protect using decorator_from_middleware.

This suggests we should make _reject public by calling it reject.

comment:6 Changed 3 years ago by lrekucki

  • Severity set to Normal
  • Type set to New feature

comment:7 Changed 3 years ago by lukeplant

  • Resolution set to fixed
  • Status changed from reopened to closed

In [16187]:

Fixed #15518 - documented requires_csrf_token

Thanks to vzima for a report that raised the issue.

comment:8 Changed 3 years ago by lukeplant

In [16189]:

Documented the edge case of needing a view that is partly CSRF protected

Refs #15518.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.