diff options
| author | Carlton Gibson <carlton.gibson@noumenal.es> | 2019-11-25 12:01:49 +0100 |
|---|---|---|
| committer | Carlton Gibson <carlton.gibson@noumenal.es> | 2019-12-02 08:58:14 +0100 |
| commit | 36f580a17f0b3cb087deadf3b65eea024f479c21 (patch) | |
| tree | cda21439c213c5246b5ac2736399cf5d2894c0cf /django/contrib/admin/options.py | |
| parent | 70311e1d00ef5b6bbbc8961eac81b5c814396a43 (diff) | |
Fixed CVE-2019-19118 -- Required edit permissions on parent model for editable inlines in admin.
Thank you to Shen Ying for reporting this issue.
Diffstat (limited to 'django/contrib/admin/options.py')
| -rw-r--r-- | django/contrib/admin/options.py | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 520e3d023e..57c3d4f4d6 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -1471,13 +1471,20 @@ class ModelAdmin(BaseModelAdmin): ) def get_inline_formsets(self, request, formsets, inline_instances, obj=None): + # Edit permissions on parent model are required for editable inlines. + can_edit_parent = self.has_change_permission(request, obj) if obj else self.has_add_permission(request) inline_admin_formsets = [] for inline, formset in zip(inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request, obj)) readonly = list(inline.get_readonly_fields(request, obj)) - has_add_permission = inline._has_add_permission(request, obj) - has_change_permission = inline.has_change_permission(request, obj) - has_delete_permission = inline.has_delete_permission(request, obj) + if can_edit_parent: + has_add_permission = inline._has_add_permission(request, obj) + has_change_permission = inline.has_change_permission(request, obj) + has_delete_permission = inline.has_delete_permission(request, obj) + else: + # Disable all edit-permissions, and overide formset settings. + has_add_permission = has_change_permission = has_delete_permission = False + formset.extra = formset.max_num = 0 has_view_permission = inline.has_view_permission(request, obj) prepopulated = dict(inline.get_prepopulated_fields(request, obj)) inline_admin_formset = helpers.InlineAdminFormSet( @@ -1542,8 +1549,12 @@ class ModelAdmin(BaseModelAdmin): else: obj = self.get_object(request, unquote(object_id), to_field) - if not self.has_view_or_change_permission(request, obj): - raise PermissionDenied + if request.method == 'POST': + if not self.has_change_permission(request, obj): + raise PermissionDenied + else: + if not self.has_view_or_change_permission(request, obj): + raise PermissionDenied if obj is None: return self._get_obj_does_not_exist_redirect(request, opts, object_id) |
