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

Fixed #23601 -- Ensured view exists in URLconf before importing it in admindocs.

parent a24cf217
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -143,10 +143,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
@@ -353,6 +353,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 = []
@@ -430,7 +435,7 @@ class RegexURLResolver(LocaleRegexProvider):

        original_lookup = lookup_view
        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))
+8 −0
Original line number Diff line number Diff line
@@ -76,6 +76,14 @@ Minor features
  <django.contrib.admin.ModelAdmin.show_full_result_count>` to control whether
  or not the full count of objects should be displayed on a filtered admin page.

:mod:`django.contrib.admindocs`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

* The view to browse view details now checks 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.

:mod:`django.contrib.auth`
^^^^^^^^^^^^^^^^^^^^^^^^^^

+11 −0
Original line number Diff line number Diff line
import sys
import unittest

from django.conf import settings
@@ -84,6 +85,16 @@ class AdminDocViewTests(AdminDocsTestCase):
        # 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(