Commit 5c0e4f39 authored by Luke Plant's avatar Luke Plant
Browse files

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
parent c26553c4
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -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>"

@@ -76,9 +77,16 @@ class CsrfMiddleware(object):
        if csrf_token is not None and \
                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