Skip to content

Commit cbe6d55

Browse files
committed
Apply autoescaping to AdminURLFieldWidget.
This is a security fix; disclosure to follow shortly.
1 parent ae35351 commit cbe6d55

File tree

2 files changed

+15
-9
lines changed

2 files changed

+15
-9
lines changed

Diff for: django/contrib/admin/widgets.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,9 @@ def render(self, name, value, attrs=None):
305305
html = super(AdminURLFieldWidget, self).render(name, value, attrs)
306306
if value:
307307
value = force_text(self._format_value(value))
308-
final_attrs = {'href': mark_safe(smart_urlquote(value))}
308+
final_attrs = {'href': smart_urlquote(value)}
309309
html = format_html(
310-
'<p class="url">{0} <a {1}>{2}</a><br />{3} {4}</p>',
310+
'<p class="url">{0} <a{1}>{2}</a><br />{3} {4}</p>',
311311
_('Currently:'), flatatt(final_attrs), value,
312312
_('Change:'), html
313313
)

Diff for: tests/admin_widgets/tests.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -321,18 +321,24 @@ def test_render_idn(self):
321321
w = widgets.AdminURLFieldWidget()
322322
self.assertHTMLEqual(
323323
conditional_escape(w.render('test', 'http://example-äüö.com')),
324-
'<p class="url">Currently:<a href="http://xn--example--7za4pnc.com">http://example-äüö.com</a><br />Change:<input class="vURLField" name="test" type="url" value="http://example-äüö.com" /></p>'
324+
'<p class="url">Currently: <a href="http://xn--example--7za4pnc.com">http://example-äüö.com</a><br />Change:<input class="vURLField" name="test" type="url" value="http://example-äüö.com" /></p>'
325325
)
326326

327327
def test_render_quoting(self):
328+
# WARNING: Don't use assertHTMLEqual in that testcase!
329+
# assertHTMLEqual will get rid of some escapes which are tested here!
328330
w = widgets.AdminURLFieldWidget()
329-
self.assertHTMLEqual(
330-
conditional_escape(w.render('test', 'http://example.com/<sometag>some text</sometag>')),
331-
'<p class="url">Currently:<a href="http://example.com/%3Csometag%3Esome%20text%3C/sometag%3E">http://example.com/&lt;sometag&gt;some text&lt;/sometag&gt;</a><br />Change:<input class="vURLField" name="test" type="url" value="http://example.com/<sometag>some text</sometag>" /></p>'
331+
self.assertEqual(
332+
w.render('test', 'http://example.com/<sometag>some text</sometag>'),
333+
'<p class="url">Currently: <a href="http://example.com/%3Csometag%3Esome%20text%3C/sometag%3E">http://example.com/&lt;sometag&gt;some text&lt;/sometag&gt;</a><br />Change: <input class="vURLField" name="test" type="url" value="http://example.com/&lt;sometag&gt;some text&lt;/sometag&gt;" /></p>'
332334
)
333-
self.assertHTMLEqual(
334-
conditional_escape(w.render('test', 'http://example-äüö.com/<sometag>some text</sometag>')),
335-
'<p class="url">Currently:<a href="http://xn--example--7za4pnc.com/%3Csometag%3Esome%20text%3C/sometag%3E">http://example-äüö.com/&lt;sometag&gt;some text&lt;/sometag&gt;</a><br />Change:<input class="vURLField" name="test" type="url" value="http://example-äüö.com/<sometag>some text</sometag>" /></p>'
335+
self.assertEqual(
336+
w.render('test', 'http://example-äüö.com/<sometag>some text</sometag>'),
337+
'<p class="url">Currently: <a href="http://xn--example--7za4pnc.com/%3Csometag%3Esome%20text%3C/sometag%3E">http://example-äüö.com/&lt;sometag&gt;some text&lt;/sometag&gt;</a><br />Change: <input class="vURLField" name="test" type="url" value="http://example-äüö.com/&lt;sometag&gt;some text&lt;/sometag&gt;" /></p>'
338+
)
339+
self.assertEqual(
340+
w.render('test', 'http://www.example.com/%C3%A4"><script>alert("XSS!")</script>"'),
341+
'<p class="url">Currently: <a href="http://www.example.com/%C3%A4%22%3E%3Cscript%3Ealert(%22XSS!%22)%3C/script%3E%22">http://www.example.com/%C3%A4&quot;&gt;&lt;script&gt;alert(&quot;XSS!&quot;)&lt;/script&gt;&quot;</a><br />Change: <input class="vURLField" name="test" type="url" value="http://www.example.com/%C3%A4&quot;&gt;&lt;script&gt;alert(&quot;XSS!&quot;)&lt;/script&gt;&quot;" /></p>'
336342
)
337343

338344

0 commit comments

Comments
 (0)