Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#28143 closed Bug (duplicate)

CSRF token fails when Debug is disabled and a custom view is used for handler404

Reported by: antigaprime Owned by: nobody
Component: CSRF Version: 1.11
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have set a custom 404 view, which uses the render function and passes context variables to the view:

def page_not_found(request, **kwargs):
    lang = request.session['lang']
    content_dict = get_all_db_content(lang, '{0}|{1}'.format('all', 'not-found'))
    variables = {
        'content_text': content_dict,
        'page_lang': "not-found-{0}".format(lang),
        'page': 'not-found',
        'page_description': get_field_db_content(lang, 'page_description_not_found'),
        'page_title': get_field_db_content(lang, 'page_title_not_found'),
    }
    return render(request, '404.html', variables, status=404)

In urls.py I have the following:

# Project libs
import mainsite.views as tn_views

handler404 = tn_views.page_not_found

When DEBUG is set to False, custom 404 templates are used, and in turn, this makes the csrf token validation for the Django Admin panel to be rejected, with a 403 error: CSRF verification failed. Request aborted..

Sometimes, I can go back, refresh the page, and attempt a new login, which will work, other times it will not.

Removing the custom 404 view from urls.py, or setting DEBUG to True (obviously), fixes the Django admin failed csrf error.

Another interesting thing is that during some tests, using CSRF_USE_SESSIONS = True and CSRF_COOKIE_AGE = None instead of cookies would fix the Django admin csrf error, but would break all csrf validations from the site's frontend.


Additional (relevant?) info:

Using Redis as a session cache.

Additional settings:

ALLOWED_HOSTS = [
    '.mysite.com',
    '.mysite.info',
]

if DEBUG:
    ALLOWED_HOSTS.extend(['.mysite.dev'])

MIDDLEWARE = [
    'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.middleware.gzip.GZipMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware',
    'mainsite.middleware.Guid',
    'mainsite.middleware.SiteLang',
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, '_templates'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'mainsite.context.site_variables',
                'mainsite.context.sitelang',
            ],
        },
    },
]

Change History (4)

comment:1 Changed 3 years ago by Tim Graham

Can you explain why Django is at fault, or are you looking for help to debug your application? In the latter case, you should TicketClosingReasons/UseSupportChannels rather than this ticket tracker.

comment:2 in reply to:  1 Changed 3 years ago by antigaprime

Replying to Tim Graham:

Can you explain why Django is at fault, or are you looking for help to debug your application? In the latter case, you should TicketClosingReasons/UseSupportChannels rather than this ticket tracker.

Well can you explain the behavior? Why would the CSRF fail for the admin panel, considering that the token is rotated after login, not before, but not for post requests in "my application"? The admin panel is not "my application", it's a default component of Django. If the behavior is erratic, it might as well be a bug, but if a Django developer comes on and states that this is "expected behavior", then there should be an explanation.

Help is always welcome, but I've already solved it. Adding the @requires_csrf_token decorator solves it, but I still thought I'd create the ticket, because there is no documentation regarding having to add this decorator, and, I can't explain the behavior regarding switching from using csrf in session and in cookies, and it randomly validating when refreshing before logging in.

comment:3 Changed 3 years ago by Tim Graham

Resolution: needsinfo
Status: newclosed

I don't think there is enough information in the report to debug the issue. For example, the get_all_db_content function isn't provided. For a good bug report, you should try to provide a minimal sample project. without any third-party dependencies to rule out a bug elsewhere.

comment:4 Changed 3 years ago by Tim Graham

Resolution: needsinfoduplicate

Duplicate of #28488 -- investigation is ongoing there.

Note: See TracTickets for help on using tickets.
Back to Top