daniyalzade/django_reverse_admin

Common Admin Site Variables are not passed to Add View. Potential security risk.

SubigyaPanta opened this issue · 1 comments

First of all, Thank you for this plugin. Really saved me a lot of time.

How to reproduce the issue

Django version : 2.2.4
django-reverse-admin: 2.3.0

I'll use the example given in this repo

model.py file

from django.db import models

class Address(models.Model):
    street = models.CharField(max_length=255)
    zipcode = models.CharField(max_length=10)
    city = models.CharField(max_length=255)
    state = models.CharField(max_length=2)

class Person(models.Model):
    name = models.CharField(max_length=255)
    addr = models.OneToOneField(Address, related_name='home_addr')

In Admin I want to override the website header so I use the variable site_header for it.
admin.py file

from django.contrib import admin
from django.db import models
from models import Person
from django_reverse_admin import ReverseModelAdmin

class PersonAdmin(ReverseModelAdmin):
    inline_type = 'tabular'
    inline_reverse = [
                      ('home_addr', {'fields': ['street', 'city', 'state', 'zipcode']}),
                      ]
admin.site.site_header = 'My Website Administration'  # <-- site_header variable
admin.site.site_title = 'My Title for website'  # <-- site_title variable
admin.site.register(Person, PersonAdmin)

site_header , site_title and many other sensitive variables such as has_permission is not available in the view. So this also opens a potential security hole in the website.

Possible Fix

I have not tried it. While trying to debug, I stumbled upon this part of the code. in your init.py file in line 256 you have this:

 context = {
            'title': _('Add %s') % force_text(opts.verbose_name),
            'adminform': adminForm,
            # 'is_popup': '_popup' in request.REQUEST,
            'is_popup': False,
            'show_delete': False,
            'media': mark_safe(media),
            'inline_admin_formsets': inline_admin_formsets,
            'errors': helpers.AdminErrorList(form, formsets),
            # 'root_path': self.admin_site.root_path,
            'app_label': opts.app_label,
        }

If you add admin variables in the context, it should be fixed:

 context = {
            **self.admin_site.each_context(request)  # <-- this line
            'title': _('Add %s') % force_text(opts.verbose_name),
            'adminform': adminForm,
            # 'is_popup': '_popup' in request.REQUEST,
            'is_popup': False,
            'show_delete': False,
            'media': mark_safe(media),
            'inline_admin_formsets': inline_admin_formsets,
            'errors': helpers.AdminErrorList(form, formsets),
            # 'root_path': self.admin_site.root_path,
            'app_label': opts.app_label,
        }

Or can also include the variables manually using:

 context = {
            'site_title': self.site_title,  # <-- this line
            'site_header': self.site_header,  # <-- this line
            'has_permission': self.has_permission(request),  # <-- this line
            'title': _('Add %s') % force_text(opts.verbose_name),
            'adminform': adminForm,
            # 'is_popup': '_popup' in request.REQUEST,
            'is_popup': False,
            'show_delete': False,
            'media': mark_safe(media),
            'inline_admin_formsets': inline_admin_formsets,
            'errors': helpers.AdminErrorList(form, formsets),
            # 'root_path': self.admin_site.root_path,
            'app_label': opts.app_label,
        }

Maybe there are other reasons because of which you didn't include them, but I think site_title, site_header and has_permission are frequently used variables and they should be included.
Please fix it and I'll upgrade the plugin. :)

Thanks for the detailed comments. I fixed it with #46 and is available on 2.7.1. Please let me know if you have any other questions.