Commit c2508990 authored by Markus Holtermann's avatar Markus Holtermann Committed by Tim Graham
Browse files

[1.7.x] Fixed #23601 -- Ensured view exists in URLconf before importing it in admindocs.

Backport of 2f16ff5a from master
parent b3569b3a
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -150,10 +150,11 @@ class ViewDetailView(BaseAdminDocsView):

    def get_context_data(self, **kwargs):
        view = self.kwargs['view']
        urlconf = urlresolvers.get_urlconf()
        if urlresolvers.get_resolver(urlconf)._is_callback(view):
            mod, func = urlresolvers.get_mod_func(view)
        try:
            view_func = getattr(import_module(mod), func)
        except (ImportError, AttributeError):
        else:
            raise Http404
        title, body, metadata = utils.parse_docstring(view_func.__doc__)
        if title:
+6 −1
Original line number Diff line number Diff line
@@ -329,6 +329,11 @@ class RegexURLResolver(LocaleRegexProvider):
            self._populate()
        return self._app_dict[language_code]

    def _is_callback(self, name):
        if not self._populated:
            self._populate()
        return name in self._callback_strs

    def resolve(self, path):
        path = force_text(path)  # path may be a reverse_lazy object
        tried = []
@@ -410,7 +415,7 @@ class RegexURLResolver(LocaleRegexProvider):
            self._populate()

        try:
            if lookup_view in self._callback_strs:
            if self._is_callback(lookup_view):
                lookup_view = get_callable(lookup_view, True)
        except (ImportError, AttributeError) as e:
            raise NoReverseMatch("Error importing '%s': %s." % (lookup_view, e))
+6 −0
Original line number Diff line number Diff line
@@ -91,3 +91,9 @@ Bugfixes
  (:ticket:`23560`).

* Fixed ``deepcopy`` on ``ErrorList`` (:ticket:`23594`).

* Made the :mod:`~django.contrib.admindocs` view to browse view details check
  if the view specified in the URL exists in the URLconf. Previously it was
  possible to import arbitrary packages from the Python path. This was not
  considered a security issue because ``admindocs`` is only accessible to staff
  users (:ticket:`23601`).
+11 −0
Original line number Diff line number Diff line
import sys
import unittest

from django.conf import settings
@@ -79,6 +80,16 @@ class AdminDocViewTests(TestCase):
        # View docstring
        self.assertContains(response, 'Base view for admindocs views.')

    def test_view_detail_illegal_import(self):
        """
        #23601 - Ensure the view exists in the URLconf.
        """
        response = self.client.get(
            reverse('django-admindocs-views-detail',
                    args=['urlpatterns_reverse.nonimported_module.view']))
        self.assertEqual(response.status_code, 404)
        self.assertNotIn("urlpatterns_reverse.nonimported_module", sys.modules)

    def test_model_index(self):
        response = self.client.get(reverse('django-admindocs-models-index'))
        self.assertContains(