Ticket #14235: 14235.diff
File 14235.diff, 3.8 KB (added by , 14 years ago) |
---|
-
django/middleware/csrf.py
13 13 from django.core.urlresolvers import get_callable 14 14 from django.utils.cache import patch_vary_headers 15 15 from django.utils.hashcompat import md5_constructor 16 from django.utils.html import escape17 16 from django.utils.safestring import mark_safe 18 17 19 18 _POST_FORM_RE = \ … … 65 64 return request.META.get("CSRF_COOKIE", None) 66 65 67 66 67 def _sanitise_token(token): 68 # Allow only alphanum, and ensure we return a 'str' for the sake of the post 69 # processing middleware. 70 return re.sub('[^a-zA-Z0-9]', '', str(token.decode('ascii', 'ignore'))) 71 72 68 73 class CsrfViewMiddleware(object): 69 74 """ 70 75 Middleware that requires a present and correct csrfmiddlewaretoken … … 90 95 # request, so it's available to the view. We'll store it in a cookie when 91 96 # we reach the response. 92 97 try: 93 request.META["CSRF_COOKIE"] = request.COOKIES[settings.CSRF_COOKIE_NAME] 98 # In case of cookies from untrusted sources, we strip anything 99 # dangerous at this point, so that the cookie + token will have the 100 # same, sanitised value. 101 request.META["CSRF_COOKIE"] = _sanitise_token(request.COOKIES[settings.CSRF_COOKIE_NAME]) 94 102 cookie_is_new = False 95 103 except KeyError: 96 104 # No cookie, so create one. This will be sent with the next … … 249 257 """Returns the matched <form> tag plus the added <input> element""" 250 258 return mark_safe(match.group() + "<div style='display:none;'>" + \ 251 259 "<input type='hidden' " + idattributes.next() + \ 252 " name='csrfmiddlewaretoken' value='" + escape(csrf_token)+ \260 " name='csrfmiddlewaretoken' value='" + csrf_token + \ 253 261 "' /></div>") 254 262 255 263 # Modify any POST forms -
tests/regressiontests/csrf_tests/tests.py
13 13 14 14 # Response/views used for CsrfResponseMiddleware and CsrfViewMiddleware tests 15 15 def post_form_response(): 16 resp = HttpResponse(content= """17 <html><body>< form method="post"><input type="text" /></form></body></html>16 resp = HttpResponse(content=u""" 17 <html><body><h1>\u00a1Unicode!<form method="post"><input type="text" /></form></body></html> 18 18 """, mimetype="text/html") 19 19 return resp 20 20 … … 58 58 59 59 class CsrfMiddlewareTest(TestCase): 60 60 # The csrf token is potentially from an untrusted source, so could have 61 # characters that need escaping 62 _csrf_id = "<1>" 61 # characters that need dealing with. 62 _csrf_id_cookie = "<1>\xc2\xa1" 63 _csrf_id = "1" 63 64 64 65 # This is a valid session token for this ID and secret key. This was generated using 65 66 # the old code that we're to be backwards-compatible with. Don't use the CSRF code … … 74 75 75 76 def _get_GET_csrf_cookie_request(self): 76 77 req = TestingHttpRequest() 77 req.COOKIES[settings.CSRF_COOKIE_NAME] = self._csrf_id 78 req.COOKIES[settings.CSRF_COOKIE_NAME] = self._csrf_id_cookie 78 79 return req 79 80 80 81 def _get_POST_csrf_cookie_request(self): … … 104 105 return req 105 106 106 107 def _check_token_present(self, response, csrf_id=None): 107 self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % escape(csrf_id or self._csrf_id))108 self.assertContains(response, "name='csrfmiddlewaretoken' value='%s'" % (csrf_id or self._csrf_id)) 108 109 109 110 # Check the post processing and outgoing cookie 110 111 def test_process_response_no_csrf_cookie(self):