403 on POST for SSL nginx proxy

When things doesn't work as they should.
Post Reply
ironhacker
Posts: 2
Joined: Tue Jan 22, 2019 3:11 am

403 on POST for SSL nginx proxy

Post by ironhacker » Tue Jan 22, 2019 3:21 am

I have a direct install, version 3.1.9 on Ubuntu 18.04 LTS. I set up a proxy using nginx and all works well with http, but when I use https, I get a "forbidden" message embedded in the response for any POST. Chrome developer tools shows a 403 related to jquery, specifically /sources/create/from/local/multiple/. POST works fine under proxied http. The issue only arises under https. Here are my proxy defs for nginx:

Code: Select all

        location @proxy_to_app {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Host $http_host;
                proxy_set_header X-Scheme $scheme;
                proxy_set_header X-SSL-Protocol $ssl_protocol;
                # we don't want nginx trying to do something clever with
                # redirects, we set the Host: header above already.
                proxy_redirect off;
                proxy_buffering off;
                proxy_pass http://app_server;
        }
There are no issues with jquery GET requests issued using SSL. Only POSTS. Any help is welcome. Thanks.


Update: 2019-01-22:

I turned on debugging and captured this error:

Code: Select all

Forbidden (Referer checking failed - Referer is malformed.): /sources/create/from/local/multiple/
This seems to be related to CSRF checks by Django that only happen when using HTTPS. No solution yet.

I believe these are the lines throwing errors in django/middleware/csrf.py:

Code: Select all

                # Make sure we have a valid URL for Referer.
                if '' in (referer.scheme, referer.netloc):
                    return self._reject(request, REASON_MALFORMED_REFERER)
scheme should be "https". Don't know about netloc, but I'm guessing it's /sources/create/from/local/multiple/

Update:

I have a solution. The csrf.py middleware reads a variable request.META.get('HTTP_REFERER'). While my browser, Chrome, says it's sending a Referer header with value https://mydomain, Django is reading the value "/sources/create/from/local/multiple/", which Chrome reports sending as the header X-Alt-Referer. Therefore, I added this line to the nginx proxy:

Code: Select all

 proxy_set_header X-Alt-Referer "https://mydomain";
I don't know if this is the proper way to handle this, but it's working for me.

Post Reply