Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSRF error on all POST requests #1912

Closed
rbu opened this issue Mar 20, 2018 · 7 comments
Assignees
Labels

Comments

@rbu
Copy link

@rbu rbu commented Mar 20, 2018

I have set up weblate using the documentation without docker. It is running from a virtualenv, served by gunicorn with an nginx in front of it. HTTPS is set up in front (I am using correct.example.com here for the correct HTTPS hostname), the following settings are changed from the default settings:

DEBUG = False
ADMINS = ...
DATABASES { ... 'ENGINE': 'django.db.backends.mysql' }
BASE_DIR = ...
TIME_ZONE = 'Europe/Berlin'
SECRET_KEY =  ...
ENABLE_HTTPS = True
ALLOWED_HOSTS = ['correct.example.com']
LOGIN_REQUIRED_URLS (uncommented example)
LOGIN_REQUIRED_URLS_EXCEPTIONS (uncommented example)

Expected behaviour

I can login

Actual behaviour

When I attempt a login: "CSRF verification failed. Request aborted."

I have observed the following:

  • Every time I reload, the CSRF token in the HTML changes even when I have CSRF_USE_SESSIONS = True. The session cookie stays identical.
  • On a single response, the "Set-cookie: csrftoken" header and the CSRF token in the HTML is different when I have CSRF_USE_SESSIONS = False
  • ENABLE_HTTPS = False or CSRF_COOKIE_SECURE = False do not help
  • With debugging enabled, I can see the following log messages:
    lib/python2.7/site-packages/django/template/defaulttags.py:66: UserWarning: A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext. as well as Forbidden (Referer checking failed - https://correct.example.com/ does not match any trusted origins.): /accounts/register/

Server configuration

Please paste the output of command ./manage.py list_versions over here

  • Weblate 2.19.1
  • Python 2.7.5
  • Django 1.11.11
  • six 1.11.0
  • social-auth-core 1.7.0
  • social-auth-app-django 2.1.0
  • django-appconf 1.0.2
  • Translate Toolkit 2.3.0
  • Whoosh 2.7.4
  • defusedxml 0.5.0
  • Git 1.8.3.1
  • Pillow (PIL) 1.1.7
  • dateutil 2.7.0
  • lxml 4.2.0
  • django-crispy-forms 1.7.2
  • compressor 2.2
  • djangorestframework 3.7.7
  • user-agents 1.1.0
  • pytz 2018.3
  • pyuca N/A
  • python-bidi 0.4.0
  • pyLibravatar N/A
  • PyYAML 3.12
  • Database backends: django.db.backends.mysql

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@rbu rbu changed the title CSRF error on login requests CSRF error on all POST requests Mar 20, 2018
@rbu

This comment has been minimized.

Copy link
Author

@rbu rbu commented Mar 20, 2018

FYI: I am seeing the weblate site rendered properly, so weblate migrate and django-admin collectstatic --no-input worked ok. I also ran django-admin changesite --set-name correct.example.com

@nijel

This comment has been minimized.

Copy link
Member

@nijel nijel commented Mar 20, 2018

What is your setting for MIDDLEWARE? Does it match the example one?

@nijel nijel added the question label Mar 20, 2018
@nijel nijel self-assigned this Mar 20, 2018
@rbu

This comment has been minimized.

Copy link
Author

@rbu rbu commented Mar 20, 2018

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'weblate.accounts.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'social_django.middleware.SocialAuthExceptionMiddleware',
    'weblate.accounts.middleware.RequireLoginMiddleware',
    'weblate.middleware.SecurityMiddleware',
    'weblate.wladmin.middleware.ConfigurationErrorsMiddleware',
]
@nijel

This comment has been minimized.

Copy link
Member

@nijel nijel commented Mar 20, 2018

The MIDDLEWARE looks correct.

Just to clarify - the token in the form should change with every request.

Can you try running with DEBUG = True, that should give you more detailed description of what went wrong. What might be causing this as well is that your browser is not sending referrer, see https://docs.djangoproject.com/en/2.0/ref/csrf/#how-it-works

@rbu

This comment has been minimized.

Copy link
Author

@rbu rbu commented Mar 21, 2018

Thank you for poining out the referrer issue. I had to manually add my domain as
CSRF_TRUSTED_ORIGINS = [".example.com"]

This is somewhat surprising to me, as Django/Weblate knows the URL of the site, e.g. the links in confirmation emails it sens contain the correct hostname.

I'll close the issue for now, but it if this setting is actually necessary to operate correctly, you'd may want to add it to the example configuration.

For what it's worth, my actual hostname is a fourth-level subdomain (translate.internal.project.org).

@rbu rbu closed this Mar 21, 2018
@nijel

This comment has been minimized.

Copy link
Member

@nijel nijel commented Mar 21, 2018

It really should not be needed, I don't have it set on any Weblate instance I'm running. As for CSRF it AFAIK compares just Host header with Referrer...

@jmvbxx

This comment has been minimized.

Copy link

@jmvbxx jmvbxx commented Jun 28, 2018

To say that I am a Django newbie would be an offence to Django newbies everywhere but this issue saved my skin. I had to do exactly what @rbu suggested and add my own domain as trusted. As soon as I did, everything worked like a charm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.