diff options
| author | Luke Plant <L.Plant.98@cantab.net> | 2011-03-15 20:37:09 +0000 |
|---|---|---|
| committer | Luke Plant <L.Plant.98@cantab.net> | 2011-03-15 20:37:09 +0000 |
| commit | 243d0bec1954ad7fab44625f1440a8ce580df26c (patch) | |
| tree | c469d617bbbe96d9c23a4f892143256298db97db /django | |
| parent | ad4118be443266685cfc7ab2d59794e0692bc944 (diff) | |
Fixed #15617 - CSRF referer checking too strict
Thanks to adam for the report.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@15840 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
| -rw-r--r-- | django/middleware/csrf.py | 6 | ||||
| -rw-r--r-- | django/utils/http.py | 18 |
2 files changed, 21 insertions, 3 deletions
diff --git a/django/middleware/csrf.py b/django/middleware/csrf.py index 2602ce8824..b5a85795b2 100644 --- a/django/middleware/csrf.py +++ b/django/middleware/csrf.py @@ -13,6 +13,7 @@ from django.conf import settings from django.core.urlresolvers import get_callable from django.utils.cache import patch_vary_headers from django.utils.hashcompat import md5_constructor +from django.utils.http import same_origin from django.utils.log import getLogger from django.utils.safestring import mark_safe from django.utils.crypto import constant_time_compare @@ -161,10 +162,9 @@ class CsrfViewMiddleware(object): ) return self._reject(request, REASON_NO_REFERER) - # The following check ensures that the referer is HTTPS, - # the domains match and the ports match - the same origin policy. + # Note that request.get_host() includes the port good_referer = 'https://%s/' % request.get_host() - if not referer.startswith(good_referer): + if not same_origin(referer, good_referer): reason = REASON_BAD_REFERER % (referer, good_referer) logger.warning('Forbidden (%s): %s' % (reason, request.path), extra={ diff --git a/django/utils/http.py b/django/utils/http.py index ae2dabf736..c93a338c30 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -3,6 +3,7 @@ import datetime import re import sys import urllib +import urlparse from email.Utils import formatdate from django.utils.encoding import smart_str, force_unicode @@ -186,3 +187,20 @@ def quote_etag(etag): """ return '"%s"' % etag.replace('\\', '\\\\').replace('"', '\\"') +if sys.version_info >= (2, 6): + def same_origin(url1, url2): + """ + Checks if two URLs are 'same-origin' + """ + p1, p2 = urlparse.urlparse(url1), urlparse.urlparse(url2) + return (p1.scheme, p1.hostname, p1.port) == (p2.scheme, p2.hostname, p2.port) +else: + # Python 2.4, 2.5 compatibility. This actually works for Python 2.6 and + # above, but the above definition is much more obviously correct and so is + # preferred going forward. + def same_origin(url1, url2): + """ + Checks if two URLs are 'same-origin' + """ + p1, p2 = urlparse.urlparse(url1), urlparse.urlparse(url2) + return p1[0:2] == p2[0:2] |
