Modification of the following patch for Django 1.8.15.
Differences include:
* moving from django/http/cookie.py (1.8.15) to
django/http/__init__.py (1.4.22)
* changing the import of django.utils.encoding.force_str (1.8.15) to
django.utils.encoding.smart_str (1.4.22) since the former does not
exist in the 1.4.22 codebase.
commit 6118ab7d0676f0d622278e5be215f14fb5410b6a
Author: Collin Anderson <cmawebsite@gmail.com>
Date: Fri Mar 11 21:36:08 2016 -0500
[1.8.x] Fixed CVE-2016-7401 -- Fixed CSRF protection bypass on a site with Google Analytics.
This is a security fix.
Backport of "refs #26158 -- rewrote http.parse_cookie() to better match
browsers." 93a135d111c2569d88d65a3f4ad9e6d9ad291452 from master
--- Django-1.4.22/django/http/__init__.py.orig 2016-09-29 08:02:02.861465688 -0700
+++ Django-1.4.22/django/http/__init__.py 2016-09-29 08:13:27.662250171 -0700
@@ -26,6 +26,10 @@ except ImportError:
from cgi import parse_qsl
import Cookie
+from django.utils import six
+from django.utils.encoding import smart_str
+from django.utils.six.moves import http_cookies
+
# httponly support exists in Python 2.6's Cookie library,
# but not in Python 2.5.
_morsel_supports_httponly = 'httponly' in Cookie.Morsel._reserved
@@ -545,20 +549,23 @@ class QueryDict(MultiValueDict):
return '&'.join(output)
def parse_cookie(cookie):
- if cookie == '':
- return {}
- if not isinstance(cookie, Cookie.BaseCookie):
- try:
- c = SimpleCookie()
- c.load(cookie)
- except Cookie.CookieError:
- # Invalid cookie
- return {}
- else:
- c = cookie
+ """
+ Return a dictionary parsed from a `Cookie:` header string.
+ """
cookiedict = {}
- for key in c.keys():
- cookiedict[key] = c.get(key).value
+ if six.PY2:
+ cookie = smart_str(cookie)
+ for chunk in cookie.split(str(';')):
+ if str('=') in chunk:
+ key, val = chunk.split(str('='), 1)
+ else:
+ # Assume an empty name per
+ key, val = str(''), chunk
+ if key or val:
+ # unquote using Python's algorithm.
+ cookiedict[key] = http_cookies._unquote(val)
return cookiedict
class BadHeaderError(ValueError):