FinalsClub / karmaworld

KarmaNotes.org v3.0
GNU Affero General Public License v3.0
7 stars 6 forks source link

CSRF fails in HTTPS #324

Closed btbonval closed 10 years ago

btbonval commented 10 years ago

This appears to be causing problems for #320 and #323 on my system. Beta appears not to have this problem. Unclear where this failure comes from.

There is related discussion in these places:

btbonval commented 10 years ago

Django CSRF rejects HTTP to HTTPS submissions: http://blog.vrplumber.com/b/2013/12/13/django-csrf-explicitly-doesnt-trust-http-when-submitting-https/

In this case we are sending HTTPS to HTTPS, but Django might not see it that way because nginx is handling the HTTPS.

btbonval commented 10 years ago

trap CSRF failure: https://docs.djangoproject.com/en/1.5/ref/settings/#std:setting-CSRF_FAILURE_VIEW

btbonval commented 10 years ago

myth confirmed. trapped CSRF failure.

> /home/vagrant/karmaworld/karmaworld/utils/csrf.py(3)csrf_failure()->None
-> pdb.set_trace()
(Pdb) list
  1     def csrf_failure(request, reason=""):
  2         import pdb
  3  ->     pdb.set_trace()
[EOF]
(Pdb) request.is_ajax()
True
(Pdb) request.method
'POST'
(Pdb) reason
u'Referer checking failed - https://localhost:6659/ does not match https://127.0.0.1:8000/.'
btbonval commented 10 years ago

There's that 127.0.0.1:8000 again. Django runs on 127.0.0.1:8000 but nginx is sitting in front of it. Surely Django can be told this (and has at least in two different places)...

btbonval commented 10 years ago

http://philipm.at/2013/django-permissivecsrf.html

"(Referer checking is not done for HTTP requests because the presence of the Referer header is not reliable enough under HTTP.)" Would explain why this is a new problem using HTTPS.

no real fixes suggested. He advertises a module (django-permissivecsrf) as a workaround with reduced security. He also recommends using entirely HTTPS on a site, but that wouldn't fix the current problem really.

btbonval commented 10 years ago

Alright well I guess it's time to Read Django Source Code. Gather 'round, children!

lib/python2.7/site-packages/django/middleware/csrf.py

REASON_BAD_REFERER = "Referer checking failed - %s does not match %s."
...
                referer = request.META.get('HTTP_REFERER')
...
                # Note that request.get_host() includes the port.
                good_referer = 'https://%s/' % request.get_host()
                if not same_origin(referer, good_referer):
                    reason = REASON_BAD_REFERER % (referer, good_referer)
...
from django.utils.http import same_origin

lib/python2.7/site-packages/django/utils/http.py

def same_origin(url1, url2):
    """
    Checks if two URLs are 'same-origin'
    """
    p1, p2 = urllib_parse.urlparse(url1), urllib_parse.urlparse(url2)
    return (p1.scheme, p1.hostname, p1.port) == (p2.scheme, p2.hostname, p2.port)

This should be easy enough to read off the request in the failed CSRF trap.

btbonval commented 10 years ago
> /home/vagrant/karmaworld/karmaworld/utils/csrf.py(3)csrf_failure()->None
-> pdb.set_trace()
(Pdb) referer = request.META.get('HTTP_REFERER')
(Pdb) referer
'https://localhost:6659/'
(Pdb) good_referer = 'https://%s/' % request.get_host()
(Pdb) good_referer
'https://127.0.0.1:8000/'

Okay. Why does request.get_host() think the things it thinks? nginx must not be passing something valuable along!

btbonval commented 10 years ago

Beta's nginx has this, whereas the VM I hadn't added it:

                proxy_set_header   Host             $host;

http://wiki.nginx.org/HttpCoreModule#.24host

$host doesn't always contain a port, thus $http_host appears to be the correct choice. Beta is fine because it uses standard ports.

btbonval commented 10 years ago

Problem solved with proxy_set_header Host $http_host;.

Will update README and Vagrant file. Ticket will be closed when this change is vetted with a whole bunch of others and pushed.

ibegoldex commented 10 years ago

btbonval commented on Feb 7, has answer perfect for me.

AndrewMagliozzi commented 10 years ago

Great!

On Wed, Oct 1, 2014 at 1:46 AM, Ibegoldex Team notifications@github.com wrote:

btbonval commented on Feb 7, has answer perfect for me.

— Reply to this email directly or view it on GitHub https://github.com/FinalsClub/karmaworld/issues/324#issuecomment-57421642 .