1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
From: Chris Lamb <lamby@debian.org>
Date: Tue, 2 Jul 2019 22:47:00 -0300
Subject: CVE-2019-12308
Backported from https://github.com/django/django/commit/c238701859a52d584f349cce15d56c8e8137c52b
---
django/contrib/admin/widgets.py | 11 +++++++++--
tests/admin_widgets/tests.py | 16 ++++++----------
2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py
index c228a3c..26de9c7 100644
--- a/django/contrib/admin/widgets.py
+++ b/django/contrib/admin/widgets.py
@@ -7,6 +7,8 @@ import copy
from django import forms
from django.db.models.deletion import CASCADE
+from django.core.exceptions import ValidationError
+from django.core.validators import URLValidator
from django.forms.utils import flatatt
from django.forms.widgets import RadioFieldRenderer
from django.template.loader import render_to_string
@@ -369,15 +371,20 @@ class AdminEmailInputWidget(forms.EmailInput):
class AdminURLFieldWidget(forms.URLInput):
- def __init__(self, attrs=None):
+ def __init__(self, attrs=None, validator_class=URLValidator):
final_attrs = {'class': 'vURLField'}
if attrs is not None:
final_attrs.update(attrs)
super(AdminURLFieldWidget, self).__init__(attrs=final_attrs)
+ self.validator = validator_class()
def render(self, name, value, attrs=None):
html = super(AdminURLFieldWidget, self).render(name, value, attrs)
- if value:
+ try:
+ self.validator(value if value else '')
+ except ValidationError:
+ pass
+ else:
value = force_text(self.format_value(value))
final_attrs = {'href': smart_urlquote(value)}
html = format_html(
diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py
index 308ec17..5a75c67 100644
--- a/tests/admin_widgets/tests.py
+++ b/tests/admin_widgets/tests.py
@@ -377,19 +377,15 @@ class AdminURLWidgetTest(SimpleTestCase):
w = widgets.AdminURLFieldWidget()
self.assertEqual(
w.render('test', 'http://example.com/<sometag>some text</sometag>'),
- '<p class="url">Currently: '
- '<a href="http://example.com/%3Csometag%3Esome%20text%3C/sometag%3E">'
- 'http://example.com/<sometag>some text</sometag></a><br />'
- 'Change: <input class="vURLField" name="test" type="url" '
- 'value="http://example.com/<sometag>some text</sometag>" /></p>'
+ '<input class="vURLField" name="test" type="url" '
+ 'value="http://example.com/<sometag>some '
+ 'text</sometag>" />'
)
self.assertEqual(
w.render('test', 'http://example-äüö.com/<sometag>some text</sometag>'),
- '<p class="url">Currently: '
- '<a href="http://xn--example--7za4pnc.com/%3Csometag%3Esome%20text%3C/sometag%3E">'
- 'http://example-äüö.com/<sometag>some text</sometag></a><br />'
- 'Change: <input class="vURLField" name="test" type="url" '
- 'value="http://example-äüö.com/<sometag>some text</sometag>" /></p>'
+ '<input class="vURLField" name="test" type="url" '
+ 'value="http://example-äüö.com/<sometag>some '
+ 'text</sometag>" />'
)
self.assertEqual(
w.render('test', 'http://www.example.com/%C3%A4"><script>alert("XSS!")</script>"'),
|