~ubuntu-branches/ubuntu/lucid/python-django/lucid-security

« back to all changes in this revision

Viewing changes to debian/patches/CVE-2014-0483.patch

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2014-09-10 13:07:32 UTC
  • Revision ID: package-import@ubuntu.com-20140910130732-ggo4hojqf9z22axy
Tags: 1.1.1-2ubuntu1.13
* SECURITY UPDATE: incorrect url validation in core.urlresolvers.reverse
  - debian/patches/CVE-2014-0480.patch: prevent reverse() from generating
    URLs pointing to other hosts in django/core/urlresolvers.py, added
    tests to tests/regressiontests/urlpatterns_reverse/{tests,urls}.py.
  - CVE-2014-0480
* SECURITY UPDATE: denial of service via file upload handling
  - debian/patches/CVE-2014-0481.patch: remove O(n) algorithm in
    django/core/files/storage.py, updated docs in
    docs/howto/custom-file-storage.txt, added tests to
    tests/modeltests/files/models.py,
    tests/regressiontests/file_storage/tests.py, backport
    get_random_string() to django/utils/crypto.py.
  - CVE-2014-0481
* SECURITY UPDATE: web session hijack via REMOTE_USER header
  - debian/patches/CVE-2014-0482.patch: modified RemoteUserMiddleware to
    logout on REMOTE_USE change in django/contrib/auth/middleware.py,
    added test to django/contrib/auth/tests/remote_user.py.
  - CVE-2014-0482
* SECURITY UPDATE: data leak in contrib.admin via query string manipulation
  - debian/patches/CVE-2014-0483.patch: validate to_field in
    django/contrib/admin/{options,exceptions}.py,
    django/contrib/admin/views/main.py, added tests to
    tests/regressiontests/admin_views/tests.py.
  - debian/patches/CVE-2014-0483-bug23329.patch: regression fix in
    django/contrib/admin/options.py, added tests to
    tests/regressiontests/admin_views/{models,tests}.py.
  - debian/patches/CVE-2014-0483-bug23431.patch: regression fix in
    django/contrib/admin/options.py, added tests to
    tests/regressiontests/admin_views/{models,tests}.py.
  - CVE-2014-0483
* debian/patches/fix_invalid_link_ftbfs.patch: remove test causing FTBFS.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Backport of:
 
2
 
 
3
From 027bd348642007617518379f8b02546abacaa6e0 Mon Sep 17 00:00:00 2001
 
4
From: Simon Charette <charette.s@gmail.com>
 
5
Date: Mon, 11 Aug 2014 15:36:16 -0400
 
6
Subject: [PATCH] [1.4.x] Prevented data leakage in contrib.admin via query
 
7
 string manipulation.
 
8
 
 
9
This is a security fix. Disclosure following shortly.
 
10
---
 
11
 django/contrib/admin/exceptions.py         |  6 ++++++
 
12
 django/contrib/admin/options.py            | 18 ++++++++++++++++++
 
13
 django/contrib/admin/views/main.py         |  6 +++++-
 
14
 docs/releases/1.4.14.txt                   | 15 +++++++++++++++
 
15
 tests/regressiontests/admin_views/tests.py | 21 +++++++++++++++++----
 
16
 5 files changed, 61 insertions(+), 5 deletions(-)
 
17
 create mode 100644 django/contrib/admin/exceptions.py
 
18
 
 
19
Index: python-django-1.1.1/django/contrib/admin/exceptions.py
 
20
===================================================================
 
21
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
22
+++ python-django-1.1.1/django/contrib/admin/exceptions.py      2014-09-10 14:38:25.038876154 -0400
 
23
@@ -0,0 +1,6 @@
 
24
+from django.core.exceptions import SuspiciousOperation
 
25
+
 
26
+
 
27
+class DisallowedModelAdminToField(SuspiciousOperation):
 
28
+    """Invalid to_field was passed to admin view via URL query string"""
 
29
+    pass
 
30
Index: python-django-1.1.1/django/contrib/admin/options.py
 
31
===================================================================
 
32
--- python-django-1.1.1.orig/django/contrib/admin/options.py    2014-09-10 14:38:25.042876154 -0400
 
33
+++ python-django-1.1.1/django/contrib/admin/options.py 2014-09-10 14:38:25.038876154 -0400
 
34
@@ -291,6 +291,24 @@
 
35
         return forms.Media(js=['%s%s' % (settings.ADMIN_MEDIA_PREFIX, url) for url in js])
 
36
     media = property(_media)
 
37
 
 
38
+    def to_field_allowed(self, request, to_field):
 
39
+        opts = self.model._meta
 
40
+
 
41
+        try:
 
42
+            field = opts.get_field(to_field)
 
43
+        except FieldDoesNotExist:
 
44
+            return False
 
45
+
 
46
+        # Make sure at least one of the models registered for this site
 
47
+        # references this field.
 
48
+        registered_models = self.admin_site._registry
 
49
+        for related_object in opts.get_all_related_objects():
 
50
+            if (related_object.model in registered_models and
 
51
+                    field == related_object.field.rel.get_related_field()):
 
52
+                return True
 
53
+
 
54
+        return False
 
55
+
 
56
     def has_add_permission(self, request):
 
57
         "Returns True if the given request has permission to add an object."
 
58
         opts = self.opts
 
59
Index: python-django-1.1.1/django/contrib/admin/views/main.py
 
60
===================================================================
 
61
--- python-django-1.1.1.orig/django/contrib/admin/views/main.py 2014-09-10 14:38:25.042876154 -0400
 
62
+++ python-django-1.1.1/django/contrib/admin/views/main.py      2014-09-10 14:38:25.038876154 -0400
 
63
@@ -1,4 +1,5 @@
 
64
 from django.contrib.admin.filterspecs import FilterSpec
 
65
+from django.contrib.admin.exceptions import DisallowedModelAdminToField
 
66
 from django.contrib.admin.options import IncorrectLookupParameters
 
67
 from django.contrib.admin.util import quote
 
68
 from django.core.exceptions import SuspiciousOperation
 
69
@@ -55,7 +56,10 @@
 
70
             self.page_num = 0
 
71
         self.show_all = ALL_VAR in request.GET
 
72
         self.is_popup = IS_POPUP_VAR in request.GET
 
73
-        self.to_field = request.GET.get(TO_FIELD_VAR)
 
74
+        to_field = request.GET.get(TO_FIELD_VAR)
 
75
+        if to_field and not model_admin.to_field_allowed(request, to_field):
 
76
+            raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field)
 
77
+        self.to_field = to_field
 
78
         self.params = dict(request.GET.items())
 
79
         if PAGE_VAR in self.params:
 
80
             del self.params[PAGE_VAR]
 
81
Index: python-django-1.1.1/tests/regressiontests/admin_views/tests.py
 
82
===================================================================
 
83
--- python-django-1.1.1.orig/tests/regressiontests/admin_views/tests.py 2014-09-10 14:38:25.042876154 -0400
 
84
+++ python-django-1.1.1/tests/regressiontests/admin_views/tests.py      2014-09-10 14:41:46.098877289 -0400
 
85
@@ -5,12 +5,14 @@
 
86
 from django.core.files import temp as tempfile
 
87
 from django.core.exceptions import SuspiciousOperation
 
88
 from django.test import TestCase
 
89
+from django.contrib.admin.exceptions import DisallowedModelAdminToField
 
90
 from django.contrib.auth.models import User, Permission
 
91
 from django.contrib.contenttypes.models import ContentType
 
92
 from django.contrib.admin.models import LogEntry, DELETION
 
93
 from django.contrib.admin.sites import LOGIN_FORM_KEY
 
94
 from django.contrib.admin.util import quote
 
95
 from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
 
96
+from django.contrib.admin.views.main import TO_FIELD_VAR
 
97
 from django.utils.cache import get_max_age
 
98
 from django.utils.html import escape
 
99
 
 
100
@@ -242,6 +244,22 @@
 
101
             "Changelist filter isn't showing options contained inside a model field 'choices' option named group."
 
102
         )
 
103
 
 
104
+    def test_disallowed_to_field(self):
 
105
+        self.assertRaises(DisallowedModelAdminToField, self.client.get,
 
106
+                          "/test_admin/admin/admin_views/section/",
 
107
+                          {TO_FIELD_VAR: 'missing_field'})
 
108
+
 
109
+        # Specifying a field that is not refered by any other model registered
 
110
+        # to this admin site should raise an exception.
 
111
+        self.assertRaises(DisallowedModelAdminToField, self.client.get,
 
112
+                          "/test_admin/admin/admin_views/section/",
 
113
+                          {TO_FIELD_VAR: 'name'})
 
114
+
 
115
+        # Specifying a field referenced by another model should be allowed.
 
116
+        response = self.client.get("/test_admin/admin/admin_views/section/", {TO_FIELD_VAR: 'id'})
 
117
+        self.assertEqual(response.status_code, 200)
 
118
+
 
119
+
 
120
 class SaveAsTests(TestCase):
 
121
     fixtures = ['admin-views-users.xml','admin-views-person.xml']
 
122