Fixed CVE-2020-13596 -- Fixed potential XSS in admin ForeignKeyRawIdWidget.
This commit is contained in:
parent
81dc710571
commit
2dd4d110c1
|
@ -12,7 +12,7 @@ from django.db.models import CASCADE
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.urls.exceptions import NoReverseMatch
|
from django.urls.exceptions import NoReverseMatch
|
||||||
from django.utils.html import smart_urlquote
|
from django.utils.html import smart_urlquote
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.http import urlencode
|
||||||
from django.utils.text import Truncator
|
from django.utils.text import Truncator
|
||||||
from django.utils.translation import get_language, gettext as _
|
from django.utils.translation import get_language, gettext as _
|
||||||
|
|
||||||
|
@ -145,8 +145,8 @@ class ForeignKeyRawIdWidget(forms.TextInput):
|
||||||
|
|
||||||
params = self.url_parameters()
|
params = self.url_parameters()
|
||||||
if params:
|
if params:
|
||||||
related_url += '?' + '&'.join('%s=%s' % (k, v) for k, v in params.items())
|
related_url += '?' + urlencode(params)
|
||||||
context['related_url'] = mark_safe(related_url)
|
context['related_url'] = related_url
|
||||||
context['link_title'] = _('Lookup')
|
context['link_title'] = _('Lookup')
|
||||||
# The JavaScript code looks for this class.
|
# The JavaScript code looks for this class.
|
||||||
context['widget']['attrs'].setdefault('class', 'vForeignKeyRawIdAdminField')
|
context['widget']['attrs'].setdefault('class', 'vForeignKeyRawIdAdminField')
|
||||||
|
|
|
@ -6,6 +6,13 @@ Django 2.2.13 release notes
|
||||||
|
|
||||||
Django 2.2.13 fixes two security issues and a regression in 2.2.12.
|
Django 2.2.13 fixes two security issues and a regression in 2.2.12.
|
||||||
|
|
||||||
|
CVE-2020-13596: Possible XSS via admin ``ForeignKeyRawIdWidget``
|
||||||
|
================================================================
|
||||||
|
|
||||||
|
Query parameters for the admin ``ForeignKeyRawIdWidget`` were not properly URL
|
||||||
|
encoded, posing an XSS attack vector. ``ForeignKeyRawIdWidget`` now
|
||||||
|
ensures query parameters are correctly URL encoded.
|
||||||
|
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,13 @@ Django 3.0.7 release notes
|
||||||
|
|
||||||
Django 3.0.7 fixes two security issues and several bugs in 3.0.6.
|
Django 3.0.7 fixes two security issues and several bugs in 3.0.6.
|
||||||
|
|
||||||
|
CVE-2020-13596: Possible XSS via admin ``ForeignKeyRawIdWidget``
|
||||||
|
================================================================
|
||||||
|
|
||||||
|
Query parameters for the admin ``ForeignKeyRawIdWidget`` were not properly URL
|
||||||
|
encoded, posing an XSS attack vector. ``ForeignKeyRawIdWidget`` now
|
||||||
|
ensures query parameters are correctly URL encoded.
|
||||||
|
|
||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,14 @@ class Band(models.Model):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
class UnsafeLimitChoicesTo(models.Model):
|
||||||
|
band = models.ForeignKey(
|
||||||
|
Band,
|
||||||
|
models.CASCADE,
|
||||||
|
limit_choices_to={'name': '"&><escapeme'},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Album(models.Model):
|
class Album(models.Model):
|
||||||
band = models.ForeignKey(Band, models.CASCADE)
|
band = models.ForeignKey(Band, models.CASCADE)
|
||||||
featuring = models.ManyToManyField(Band, related_name='featured')
|
featuring = models.ManyToManyField(Band, related_name='featured')
|
||||||
|
|
|
@ -24,6 +24,7 @@ from django.utils import translation
|
||||||
from .models import (
|
from .models import (
|
||||||
Advisor, Album, Band, Bee, Car, Company, Event, Honeycomb, Individual,
|
Advisor, Album, Band, Bee, Car, Company, Event, Honeycomb, Individual,
|
||||||
Inventory, Member, MyFileField, Profile, School, Student,
|
Inventory, Member, MyFileField, Profile, School, Student,
|
||||||
|
UnsafeLimitChoicesTo,
|
||||||
)
|
)
|
||||||
from .widgetadmin import site as widget_admin_site
|
from .widgetadmin import site as widget_admin_site
|
||||||
|
|
||||||
|
@ -617,6 +618,16 @@ class ForeignKeyRawIdWidgetTest(TestCase):
|
||||||
'Hidden</a></strong>' % {'pk': hidden.pk}
|
'Hidden</a></strong>' % {'pk': hidden.pk}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_render_unsafe_limit_choices_to(self):
|
||||||
|
rel = UnsafeLimitChoicesTo._meta.get_field('band').remote_field
|
||||||
|
w = widgets.ForeignKeyRawIdWidget(rel, widget_admin_site)
|
||||||
|
self.assertHTMLEqual(
|
||||||
|
w.render('test', None),
|
||||||
|
'<input type="text" name="test" class="vForeignKeyRawIdAdminField">\n'
|
||||||
|
'<a href="/admin_widgets/band/?name=%22%26%3E%3Cescapeme&_to_field=id" '
|
||||||
|
'class="related-lookup" id="lookup_id_test" title="Lookup"></a>'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='admin_widgets.urls')
|
@override_settings(ROOT_URLCONF='admin_widgets.urls')
|
||||||
class ManyToManyRawIdWidgetTest(TestCase):
|
class ManyToManyRawIdWidgetTest(TestCase):
|
||||||
|
|
Loading…
Reference in New Issue