﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
22486	urlresolvers.reverse() security fix (1.5.6) breaks when a view is a partial	Robert Coup	Tim Graham	"The changes in the recent security fix for `reverse()` [https://github.com/django/django/commit/8b93b31487d6d3b0fcbbd0498991ea0db9088054 Fixed a remote code execution vulnerabilty in URL reversing] ([https://www.djangoproject.com/weblog/2014/apr/21/security/ CVE-2014-0472]) break when any view in the urlpatterns is a functools partial.

Django 1.5.6 / Py2.6.5 / Linux.

pseudo-code:


{{{
# myapp/views.py
def my_view(request, **kwargs):
     return HttpResponse(str(kwargs))

my_view2 = functools.partial(my_view, some_arg=123)

# myapp/urls.py
urlpatterns = patterns('my_app.views',
   ('^some_view/$', 'normal_view'),  # a normal function/class view
   ('^breaks/$', 'my_view2'),        # partial-wrapped view
)

}}}

Then

{{{
>>> from django.core.urlresolvers import reverse
>>> reverse('my_app.some_view')
django/core/urlresolvers.pyc in reverse(viewname, urlconf, args, kwargs, prefix, current_app)
    514             resolver = get_ns_resolver(ns_pattern, resolver)
    515
--> 516     return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
    517
    518 reverse_lazy = lazy(reverse, str)

django/core/urlresolvers.pyc in _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs)
    393
    394         if not self._populated:
--> 395             self._populate()
    396
    397         try:

django/core/urlresolvers.pyc in _populate(self)
    285                 else:
    286                     parent = normalize(pattern.regex.pattern)
--> 287                     for name in pattern.reverse_dict:
    288                         for matches, pat, defaults in pattern.reverse_dict.getlist(name):
    289                             new_matches = []

django/core/urlresolvers.pyc in reverse_dict(self)
    310         language_code = get_language()
    311         if language_code not in self._reverse_dict:
--> 312             self._populate()
    313         return self._reverse_dict[language_code]
    314

django/core/urlresolvers.pyc in _populate(self)
    271                 callback = pattern._callback
    272                 if not hasattr(callback, '__name__'):
--> 273                     lookup_str = callback.__module__ + ""."" + callback.__class__.__name__
    274                 else:
    275                     lookup_str = callback.__module__ + ""."" + callback.__name__

AttributeError: 'functools.partial' object has no attribute '__module__'
}}}

Changing the view to use `functools.update_wrapper()` (as it probably should) and it works okay:

{{{
my_view2 = functools.partial(my_view, some_arg=123)
functools.update_wrapper(my_view2, my_view)
}}}

"	Bug	closed	Core (URLs)	dev	Release blocker	fixed		luke@…	Accepted	1	0	0	0	0	0
