mirror of
https://github.com/django/django.git
synced 2025-06-08 04:59:13 +00:00
[1.7.x] Fixed #24461 -- Fixed XSS issue in ModelAdmin.readonly_fields
This commit is contained in:
parent
5a3b531121
commit
2654e1b939
@ -193,7 +193,7 @@ class AdminReadonlyField(object):
|
|||||||
if getattr(attr, "allow_tags", False):
|
if getattr(attr, "allow_tags", False):
|
||||||
result_repr = mark_safe(result_repr)
|
result_repr = mark_safe(result_repr)
|
||||||
else:
|
else:
|
||||||
result_repr = linebreaksbr(result_repr)
|
result_repr = linebreaksbr(result_repr, autoescape=True)
|
||||||
else:
|
else:
|
||||||
if isinstance(f.rel, ManyToManyRel) and value is not None:
|
if isinstance(f.rel, ManyToManyRel) and value is not None:
|
||||||
result_repr = ", ".join(map(six.text_type, value.all()))
|
result_repr = ", ".join(map(six.text_type, value.all()))
|
||||||
|
@ -2,9 +2,23 @@
|
|||||||
Django 1.7.6 release notes
|
Django 1.7.6 release notes
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
*Under Development*
|
*March 9, 2015*
|
||||||
|
|
||||||
Django 1.7.6 fixes several bugs in 1.7.5.
|
Django 1.7.6 fixes a security issue and several bugs in 1.7.5.
|
||||||
|
|
||||||
|
Mitigated an XSS attack via properties in ``ModelAdmin.readonly_fields``
|
||||||
|
========================================================================
|
||||||
|
|
||||||
|
The :attr:`ModelAdmin.readonly_fields
|
||||||
|
<django.contrib.admin.ModelAdmin.readonly_fields>` attribute in the Django
|
||||||
|
admin allows displaying model fields and model attributes. While the former
|
||||||
|
were correctly escaped, the latter were not. Thus untrusted content could be
|
||||||
|
injected into the admin, presenting an exploitation vector for XSS attacks.
|
||||||
|
|
||||||
|
In this vulnerability, every model attribute used in ``readonly_fields`` that
|
||||||
|
is not an actual model field (e.g. a :class:`property`) will **fail to be
|
||||||
|
escaped** even if that attribute is not marked as safe. In this release,
|
||||||
|
autoescaping is now correctly applied.
|
||||||
|
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
@ -860,7 +860,7 @@ class GetFormsetsArgumentCheckingAdmin(admin.ModelAdmin):
|
|||||||
site = admin.AdminSite(name="admin")
|
site = admin.AdminSite(name="admin")
|
||||||
site.register(Article, ArticleAdmin)
|
site.register(Article, ArticleAdmin)
|
||||||
site.register(CustomArticle, CustomArticleAdmin)
|
site.register(CustomArticle, CustomArticleAdmin)
|
||||||
site.register(Section, save_as=True, inlines=[ArticleInline])
|
site.register(Section, save_as=True, inlines=[ArticleInline], readonly_fields=['name_property'])
|
||||||
site.register(ModelWithStringPrimaryKey)
|
site.register(ModelWithStringPrimaryKey)
|
||||||
site.register(Color)
|
site.register(Color)
|
||||||
site.register(Thing, ThingAdmin)
|
site.register(Thing, ThingAdmin)
|
||||||
|
@ -22,6 +22,13 @@ class Section(models.Model):
|
|||||||
"""
|
"""
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name_property(self):
|
||||||
|
"""
|
||||||
|
A property that simply returns the name. Used to test #24461
|
||||||
|
"""
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class Article(models.Model):
|
class Article(models.Model):
|
||||||
|
@ -3862,6 +3862,15 @@ class ReadonlyTest(TestCase):
|
|||||||
self.assertContains(response, '<label for="id_public">Overridden public label:</label>', html=True)
|
self.assertContains(response, '<label for="id_public">Overridden public label:</label>', html=True)
|
||||||
self.assertNotContains(response, "Some help text for the date (with unicode ŠĐĆŽćžšđ)")
|
self.assertNotContains(response, "Some help text for the date (with unicode ŠĐĆŽćžšđ)")
|
||||||
|
|
||||||
|
def test_correct_autoescaping(self):
|
||||||
|
"""
|
||||||
|
Make sure that non-field readonly elements are properly autoescaped (#24461)
|
||||||
|
"""
|
||||||
|
section = Section.objects.create(name='<a>evil</a>')
|
||||||
|
response = self.client.get(reverse('admin:admin_views_section_change', args=(section.pk,)))
|
||||||
|
self.assertNotContains(response, "<a>evil</a>", status_code=200)
|
||||||
|
self.assertContains(response, "<a>evil</a>", status_code=200)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
|
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
|
||||||
class LimitChoicesToInAdminTest(TestCase):
|
class LimitChoicesToInAdminTest(TestCase):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user