Search code examples
djangocsrfdjango-cmssame-origin-policydjango-csrf

Can't edit anything in Django CMS due to cross-origin error


About three months ago, I upgraded our old Django and CMS application to the (then) latest LTS versions (4.2.3 for Django, 3.11.3 for django-cms). After the upgrade, I got the following error when I tried to edit anything from the CMS toolbar or the CMS plugins after a successful login:

SecurityError: Blocked a frame with origin "http://localhost:8000" from accessing a cross-origin frame.

A short Google search later I was able to fix the issue by setting the CSRF_TRUSTED_ORIGINS in settings.py (depending on the environment).

This worked like a charm until a few weeks ago, when suddenly the same error appeared again. This happens on all our environments - including local - despite the fact that nothing new was deployed since the beginning of July '23.

First, I tried everything in this guide: https://noumenal.es/notes/til/django/csrf-trusted-origins/

Our staging and production django app is behind a proxy, so I verified that HttpRequest.is_secure() returns True and the X-Forwarded-Proto header is set to https in the production environment. But this happens also on my local machine, where there is no HTTPS. I also verified that the CSRF cookie value and the CSRF token param in requests are, in fact, the same.

Then I tried to install the django-cors-headers module and set the CORS_ALLOWED_ORIGINS, but no luck there.

For local dev, I have these settings:

ALLOWED_HOSTS = ['localhost']
CSRF_TRUSTED_ORIGINS = ['http://localhost:8000']
CORS_ALLOWED_ORIGINS = ['http://localhost:8000']

The logs don't say anything at all about this matter.

Is there any other reason than a misconfiguration of CSRF_TRUSTED_ORIGINS why this message suddenly shows up?


Solution

  • Depending on what version you were upgrading from, you may have missed a bit in the upgrade notes, what's new in 3.7.2.

    Django 3.0 changed the default behaviour of the XFrameOptionsMiddleware from SAMEORIGIN to DENY. In order for django CMS to function, X_FRAME_OPTIONS needs to be set to SAMEORIGIN in the settings.py:

    X_FRAME_OPTIONS = 'SAMEORIGIN'
    

    This option is also available on each page within the CMS, located in the advanced settings. Allowing you to override the default in your settings file.