mirror of https://github.com/django/django.git
Fixed CsrfMiddleware post processing so that it in the presence of multiple
POST <form>s, only one <input> tag is added with an id, for HTML validity. git-svn-id: http://code.djangoproject.com/svn/django/trunk@2900 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
c26553c4f9
commit
5c0e4f3908
|
@ -9,6 +9,7 @@ from django.conf import settings
|
||||||
from django.http import HttpResponseForbidden
|
from django.http import HttpResponseForbidden
|
||||||
import md5
|
import md5
|
||||||
import re
|
import re
|
||||||
|
import itertools
|
||||||
|
|
||||||
_ERROR_MSG = "<h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p>"
|
_ERROR_MSG = "<h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p>"
|
||||||
|
|
||||||
|
@ -19,7 +20,7 @@ _HTML_TYPES = ('text/html', 'application/xhtml+xml')
|
||||||
|
|
||||||
def _make_token(session_id):
|
def _make_token(session_id):
|
||||||
return md5.new(settings.SECRET_KEY + session_id).hexdigest()
|
return md5.new(settings.SECRET_KEY + session_id).hexdigest()
|
||||||
|
|
||||||
class CsrfMiddleware(object):
|
class CsrfMiddleware(object):
|
||||||
"""Django middleware that adds protection against Cross Site
|
"""Django middleware that adds protection against Cross Site
|
||||||
Request Forgeries by adding hidden form fields to POST forms and
|
Request Forgeries by adding hidden form fields to POST forms and
|
||||||
|
@ -57,7 +58,7 @@ class CsrfMiddleware(object):
|
||||||
return HttpResponseForbidden(_ERROR_MSG)
|
return HttpResponseForbidden(_ERROR_MSG)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def process_response(self, request, response):
|
def process_response(self, request, response):
|
||||||
csrf_token = None
|
csrf_token = None
|
||||||
try:
|
try:
|
||||||
|
@ -74,11 +75,18 @@ class CsrfMiddleware(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if csrf_token is not None and \
|
if csrf_token is not None and \
|
||||||
response['Content-Type'].split(';')[0] in _HTML_TYPES:
|
response['Content-Type'].split(';')[0] in _HTML_TYPES:
|
||||||
|
|
||||||
|
# ensure we don't add the 'id' attribute twice (HTML validity)
|
||||||
|
idattributes = itertools.chain(("id='csrfmiddlewaretoken'",),
|
||||||
|
itertools.repeat(''))
|
||||||
|
def add_csrf_field(match):
|
||||||
|
"""Returns the matched <form> tag plus the added <input> element"""
|
||||||
|
return match.group() + "<div style='display:none;'>" + \
|
||||||
|
"<input type='hidden' " + idattributes.next() + \
|
||||||
|
" name='csrfmiddlewaretoken' value='" + csrf_token + \
|
||||||
|
"' /></div>"
|
||||||
|
|
||||||
# Modify any POST forms
|
# Modify any POST forms
|
||||||
extra_field = "<div style='display:none;'>" + \
|
response.content = _POST_FORM_RE.sub(add_csrf_field, response.content)
|
||||||
"<input type='hidden' id='csrfmiddlewaretoken' name='csrfmiddlewaretoken' value='" + \
|
|
||||||
csrf_token + "' /></div>"
|
|
||||||
response.content = _POST_FORM_RE.sub('\\1' + extra_field, response.content)
|
|
||||||
return response
|
return response
|
||||||
|
|
Loading…
Reference in New Issue