From 93c538694e6b14a29cb0f52b784a3bfed604fda6 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Wed, 6 Jul 2016 15:41:06 -0400 Subject: [PATCH] Fixed XSS in admin's add/change related popup. This is a security fix. --- .../static/admin/js/admin/RelatedObjectLookups.js | 2 +- django/views/debug.py | 4 ++-- docs/releases/1.8.14.txt | 15 +++++++++++++-- docs/releases/1.9.8.txt | 15 +++++++++++++-- tests/admin_views/tests.py | 4 ++-- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js index 0f02051e6b..d2dda892b1 100644 --- a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js +++ b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js @@ -104,7 +104,7 @@ var selects = $(selectsSelector); selects.find('option').each(function() { if (this.value === objId) { - this.innerHTML = newRepr; + this.textContent = newRepr; this.value = newId; } }); diff --git a/django/views/debug.py b/django/views/debug.py index 56329325d3..eac0a77605 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -636,13 +636,13 @@ TECHNICAL_500_TEMPLATE = (""" var s = link.getElementsByTagName('span')[0]; var uarr = String.fromCharCode(0x25b6); var darr = String.fromCharCode(0x25bc); - s.innerHTML = s.innerHTML == uarr ? darr : uarr; + s.textContent = s.textContent == uarr ? darr : uarr; return false; } function switchPastebinFriendly(link) { s1 = "Switch to copy-and-paste view"; s2 = "Switch back to interactive view"; - link.innerHTML = link.innerHTML.trim() == s1 ? s2: s1; + link.textContent = link.textContent.trim() == s1 ? s2: s1; toggle('browserTraceback', 'pastebinTraceback'); return false; } diff --git a/docs/releases/1.8.14.txt b/docs/releases/1.8.14.txt index 6311172abc..31a304f7c0 100644 --- a/docs/releases/1.8.14.txt +++ b/docs/releases/1.8.14.txt @@ -2,9 +2,20 @@ Django 1.8.14 release notes =========================== -*Under development* +*July 18, 2016* -Django 1.8.14 fixes several bugs in 1.8.13. +Django 1.8.14 fixes a security issue and a bug in 1.8.13. + +XSS in admin's add/change related popup +======================================= + +Unsafe usage of JavaScript's ``Element.innerHTML`` could result in XSS in the +admin's add/change related popup. ``Element.textContent`` is now used to +prevent execution of the data. + +The debug view also used ``innerHTML``. Although a security issue wasn't +identified there, out of an abundance of caution it's also updated to use +``textContent``. Bugfixes ======== diff --git a/docs/releases/1.9.8.txt b/docs/releases/1.9.8.txt index 8db5c3d01f..08ba5ae08f 100644 --- a/docs/releases/1.9.8.txt +++ b/docs/releases/1.9.8.txt @@ -2,9 +2,20 @@ Django 1.9.8 release notes ========================== -*Under development* +*July 18, 2016* -Django 1.9.8 fixes several bugs in 1.9.7. +Django 1.9.8 fixes a security issue and several bugs in 1.9.7. + +XSS in admin's add/change related popup +======================================= + +Unsafe usage of JavaScript's ``Element.innerHTML`` could result in XSS in the +admin's add/change related popup. ``Element.textContent`` is now used to +prevent execution of the data. + +The debug view also used ``innerHTML``. Although a security issue wasn't +identified there, out of an abundance of caution it's also updated to use +``textContent``. Bugfixes ======== diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 2886c94bd5..8f12fcd068 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -4475,11 +4475,11 @@ class SeleniumTests(AdminSeleniumTestCase): self.wait_for_text('#content h1', 'Change section') name_input = self.selenium.find_element_by_id('id_name') name_input.clear() - name_input.send_keys('edited section') + name_input.send_keys('edited section') self.selenium.find_element_by_xpath('//input[@value="Save"]').click() self.selenium.switch_to.window(self.selenium.window_handles[0]) select = Select(self.selenium.find_element_by_id('id_form-0-section')) - self.assertEqual(select.first_selected_option.text, 'edited section') + self.assertEqual(select.first_selected_option.text, 'edited section') # Add popup self.selenium.find_element_by_id('add_id_form-0-section').click()