Author: gwilson
Date: 2007-11-18 00:51:20 -0600 (Sun, 18 Nov 2007)
New Revision: 6691

Modified:
   django/trunk/django/contrib/admin/media/js/admin/RelatedObjectLookups.js
   django/trunk/django/contrib/admin/views/main.py
Log:
Fixed #5880 -- Fixed an XSS hole in the admin interface.
 * Escaped text that gets sent after saving the admin foreignkey popup form.
 * Added quotes around the second argument passed to 
`opener.dismissAddAnotherPopup` to make the function also work when a text 
field is used as the primary key.
 * Added a `html_unescape` javascript function to unescape the strings passed 
in to the `dismissAddAnotherPopup` function so that the added choice displays 
correctly in the dropdown box.


Modified: 
django/trunk/django/contrib/admin/media/js/admin/RelatedObjectLookups.js
===================================================================
--- django/trunk/django/contrib/admin/media/js/admin/RelatedObjectLookups.js    
2007-11-18 05:48:24 UTC (rev 6690)
+++ django/trunk/django/contrib/admin/media/js/admin/RelatedObjectLookups.js    
2007-11-18 06:51:20 UTC (rev 6691)
@@ -1,6 +1,16 @@
 // Handles related-objects functionality: lookup link for raw_id_admin=True
 // and Add Another links.
 
+function html_unescape(text) {
+    // Unescape a string that was escaped using django.utils.html.escape.
+    text = text.replace(/&lt;/g, '<');
+    text = text.replace(/&gt;/g, '>');
+    text = text.replace(/&quot;/g, '"');
+    text = text.replace(/&#39;/g, "'");
+    text = text.replace(/&amp;/g, '&');
+    return text;
+}
+
 function showRelatedObjectLookupPopup(triggeringLink) {
     var name = triggeringLink.id.replace(/^lookup_/, '');
     // IE doesn't like periods in the window name, so convert temporarily.
@@ -42,6 +52,10 @@
 }
 
 function dismissAddAnotherPopup(win, newId, newRepr) {
+    // newId and newRepr are expected to have previously been escaped by
+    // django.utils.html.escape.
+    newId = html_unescape(newId);
+    newRepr = html_unescape(newRepr);
     var name = win.name.replace(/___/g, '.');
     var elem = document.getElementById(name);
     if (elem) {

Modified: django/trunk/django/contrib/admin/views/main.py
===================================================================
--- django/trunk/django/contrib/admin/views/main.py     2007-11-18 05:48:24 UTC 
(rev 6690)
+++ django/trunk/django/contrib/admin/views/main.py     2007-11-18 06:51:20 UTC 
(rev 6691)
@@ -273,10 +273,9 @@
                     post_url_continue += "?_popup=1"
                 return HttpResponseRedirect(post_url_continue % pk_value)
             if "_popup" in request.POST:
-                if type(pk_value) is str: # Quote if string, so JavaScript 
doesn't think it's a variable.
-                    pk_value = '"%s"' % pk_value.replace('"', '\\"')
-                return HttpResponse('<script 
type="text/javascript">opener.dismissAddAnotherPopup(window, %s, 
"%s");</script>' % \
-                    (pk_value, force_unicode(new_object).replace('"', '\\"')))
+                return HttpResponse('<script 
type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", 
"%s");</script>' % \
+                    # escape() calls force_unicode.
+                    (escape(pk_value), escape(new_object)))
             elif "_addanother" in request.POST:
                 request.user.message_set.create(message=msg + ' ' + (_("You 
may add another %s below.") % force_unicode(opts.verbose_name)))
                 return HttpResponseRedirect(request.path)


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to