diff options
| author | Luke Plant <L.Plant.98@cantab.net> | 2006-05-11 22:32:47 +0000 |
|---|---|---|
| committer | Luke Plant <L.Plant.98@cantab.net> | 2006-05-11 22:32:47 +0000 |
| commit | 5c0e4f3908d7782939b4a16af3d3be9f07d5504b (patch) | |
| tree | c2ccc08ba1e9c76b5b1ae849ccdd1d0e0dc1dd16 | |
| parent | c26553c4f91a2a0ac1ca8d173888c414fc9cecda (diff) | |
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
| -rw-r--r-- | django/contrib/csrf/middleware.py | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/django/contrib/csrf/middleware.py b/django/contrib/csrf/middleware.py index dee6f4f429..f6f78867dc 100644 --- a/django/contrib/csrf/middleware.py +++ b/django/contrib/csrf/middleware.py @@ -9,6 +9,7 @@ from django.conf import settings from django.http import HttpResponseForbidden import md5 import re +import itertools _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): return md5.new(settings.SECRET_KEY + session_id).hexdigest() - + class CsrfMiddleware(object): """Django middleware that adds protection against Cross Site Request Forgeries by adding hidden form fields to POST forms and @@ -57,7 +58,7 @@ class CsrfMiddleware(object): return HttpResponseForbidden(_ERROR_MSG) return None - + def process_response(self, request, response): csrf_token = None try: @@ -74,11 +75,18 @@ class CsrfMiddleware(object): pass 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 - extra_field = "<div style='display:none;'>" + \ - "<input type='hidden' id='csrfmiddlewaretoken' name='csrfmiddlewaretoken' value='" + \ - csrf_token + "' /></div>" - response.content = _POST_FORM_RE.sub('\\1' + extra_field, response.content) + response.content = _POST_FORM_RE.sub(add_csrf_field, response.content) return response |
