CSRF verification Failed - Referer is insecure while host is secure
Asked Answered
J

2

12

I upgraded Django from 1.8 to 1.9. Afterwards, I get this error on my localhost after the Django admin login:

Referer checking failed - Referer is insecure while host is secure.

Everything works fine in production. Below is a snippet of my settings.py file:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
Jam answered 7/1, 2016 at 17:11 Comment(1)
i guess you are using http in development. so the app must be configured for using http in your local.py (or similar).Fivefinger
E
10

I had this error when I was switching from ssl setup to no ssl and forgot to remove last line from upstream configuration in nginx config:

  location / {
    proxy_pass http://127.0.0.1:8085;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host; #:8080;
    #proxy_set_header X-FORWARDED-PROTO https;

  }
Ectoenzyme answered 1/8, 2019 at 9:40 Comment(0)
P
6

Those lines in your settings.py file are fine on production because you're using an SSL certificate attached to your domain. However, on local you're probably using http://localhost:8000 or something similar. If you try to connect via https://localhost:{{YOUR_PORT_NUMBER}} you'll most likely get an error like ERR_SSL_PROTOCOL_ERROR.

The issue is in lines 167-168 of django/django/middleware/csrf.py. When you're using https on production, request.is_secure() is returning True...which requires that the HTTP_REFERER also be true or you'll get the error you referenced.

One solution would be to adjust your settings.py file depending on whether you're in your local or production environment. That way you can add those three lines to a settings_production.py file that imports other settings that are common to both localhost and your production server. Your localhost would use a different set of settings that don't include those lines.

Portsalut answered 7/1, 2016 at 19:20 Comment(5)
Yes. I get your point. before those lines I've specified in my question, there is this condition if not ENVIRONMENT == 'localhost'. Meaning those lines I've specified in my question only executes in production. So what do I have to add to my settings to prevent this error?Jam
Just to check, if you completely delete those three lines does the site work on localhost? What's the error that happens then? The issue is that your HTTP_REFERER meta tag is not using https on localhost. See lines 167-168 of django/django/middleware/csrf.pyPortsalut
I still get the same error when i comment out those three lines.Jam
You'd have to show the rest of your settings.py file (make sure to comment out or remove any keys). The basic solution is to remove anything in your local settings.py that refers to https...so I'd just be looking for the setting that is forcing https use on local.Portsalut
I was able to fix this. Another library django-cors-headers i was using was causing the problem. I had to avoid that by adding CORS_REPLACE_HTTPS_REFERER = True. And the problem is solved. :) Thanks anyway.Jam

© 2022 - 2024 — McMap. All rights reserved.