diff options
| author | Carlton Gibson <carlton.gibson@noumenal.es> | 2019-11-25 15:23:52 +0100 |
|---|---|---|
| committer | Carlton Gibson <carlton.gibson@noumenal.es> | 2019-12-02 08:57:44 +0100 |
| commit | 092cd66cf3c3e175acce698d6ca2012068d878fa (patch) | |
| tree | 7632a9bd92e8bdc07a6e2e082a895d6c7101e965 /django/contrib/admin/options.py | |
| parent | db0cc4ae96c4752d10d98a3c7f2c48f813bf8a7f (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 85896bed7e..795d20f96a 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -1464,13 +1464,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( @@ -1535,8 +1542,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) |
