mirror of
https://github.com/django/django.git
synced 2025-08-04 10:59:45 +00:00
Fixed #20869 -- made CSRF tokens change every request by salt-encrypting them
Note that the cookie is not changed every request, just the token retrieved by the `get_token()` method (used also by the `{% csrf_token %}` tag). While at it, made token validation strict: Where, before, any length was accepted and non-ASCII chars were ignored, we now treat anything other than `[A-Za-z0-9]{64}` as invalid (except for 32-char tokens, which, for backwards-compatibility, are accepted and replaced by 64-char ones). Thanks Trac user patrys for reporting, github user adambrenecki for initial patch, Tim Graham for help, and Curtis Maloney, Collin Anderson, Florian Apolloner, Markus Holtermann & Jon Dufresne for reviews.
This commit is contained in:
parent
6d9c5d46e6
commit
5112e65ef2
8 changed files with 241 additions and 70 deletions
|
@ -2,9 +2,13 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from django.forms import CharField, Form, Media
|
||||
from django.http import HttpRequest
|
||||
from django.middleware.csrf import CsrfViewMiddleware, get_token
|
||||
from django.middleware.csrf import (
|
||||
CsrfViewMiddleware, _compare_salted_tokens as equivalent_tokens, get_token,
|
||||
)
|
||||
from django.template import TemplateDoesNotExist, TemplateSyntaxError
|
||||
from django.template.backends.dummy import TemplateStrings
|
||||
from django.test import SimpleTestCase
|
||||
|
@ -81,11 +85,10 @@ class TemplateStringsTests(SimpleTestCase):
|
|||
template = self.engine.get_template('template_backends/csrf.html')
|
||||
content = template.render(request=request)
|
||||
|
||||
expected = (
|
||||
'<input type="hidden" name="csrfmiddlewaretoken" '
|
||||
'value="{}" />'.format(get_token(request)))
|
||||
|
||||
self.assertHTMLEqual(content, expected)
|
||||
expected = '<input type="hidden" name="csrfmiddlewaretoken" value="([^"]+)" />'
|
||||
match = re.match(expected, content) or re.match(expected.replace('"', "'"), content)
|
||||
self.assertTrue(match, "hidden csrftoken field not found in output")
|
||||
self.assertTrue(equivalent_tokens(match.group(1), get_token(request)))
|
||||
|
||||
def test_no_directory_traversal(self):
|
||||
with self.assertRaises(TemplateDoesNotExist):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue