VYPR
Moderate severityNVD Advisory· Published Feb 14, 2011· Updated Apr 29, 2026

CVE-2011-0697

CVE-2011-0697

Description

Cross-site scripting (XSS) vulnerability in Django 1.1.x before 1.1.4 and 1.2.x before 1.2.5 might allow remote attackers to inject arbitrary web script or HTML via a filename associated with a file upload.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
DjangoPyPI
>= 1.1, < 1.1.41.1.4
DjangoPyPI
>= 1.2, < 1.2.51.2.5

Affected products

9
  • cpe:2.3:a:djangoproject:django:1.1:*:*:*:*:*:*:*+ 8 more
    • cpe:2.3:a:djangoproject:django:1.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.1.0:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.1.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.1.3:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.2.1:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.2.2:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.2.3:*:*:*:*:*:*:*
    • cpe:2.3:a:djangoproject:django:1.2.4:*:*:*:*:*:*:*

Patches

4
1966786d2dde

[1.1.X] Fixed security issue in AdminFileWidget. Release and disclosure forthcoming.

https://github.com/django/djangoCarl MeyerFeb 9, 2011via ghsa
2 files changed · +17 1
  • django/contrib/admin/widgets.py+1 1 modified
    @@ -93,7 +93,7 @@ def render(self, name, value, attrs=None):
             output = []
             if value and hasattr(value, "url"):
                 output.append('%s <a target="_blank" href="%s">%s</a> <br />%s ' % \
    -                (_('Currently:'), value.url, value, _('Change:')))
    +                (_('Currently:'), escape(value.url), escape(value), _('Change:')))
             output.append(super(AdminFileWidget, self).render(name, value, attrs))
             return mark_safe(u''.join(output))
     
    
  • tests/regressiontests/admin_widgets/tests.py+16 0 modified
    @@ -154,3 +154,19 @@ def test_nonexistent_target_id(self):
                 post_data)
             self.assertContains(response,
                 'Select a valid choice. That choice is not one of the available choices.')
    +
    +class AdminFileWidgetTest(DjangoTestCase):
    +    def test_render_escapes_html(self):
    +        class StrangeFieldFile(object):
    +            url = "something?chapter=1&sect=2&copy=3&lang=en"
    +
    +            def __unicode__(self):
    +                return u'''something<div onclick="alert('oops')">.jpg'''
    +
    +        widget = widgets.AdminFileWidget()
    +        field = StrangeFieldFile()
    +        output = widget.render('myfile', field)
    +        self.assertFalse(field.url in output)
    +        self.assertTrue(u'href="something?chapter=1&amp;sect=2&amp;copy=3&amp;lang=en"' in output)
    +        self.assertFalse(unicode(field) in output)
    +        self.assertTrue(u'something&lt;div onclick=&quot;alert(&#39;oops&#39;)&quot;&gt;.jpg' in output)
    
1f814a954784

[1.2.X] Fixed security issue in AdminFileWidget. Disclosure and release forthcoming.

https://github.com/django/djangoCarl MeyerFeb 9, 2011via ghsa
2 files changed · +17 1
  • django/contrib/admin/widgets.py+1 1 modified
    @@ -96,7 +96,7 @@ def render(self, name, value, attrs=None):
             output = []
             if value and hasattr(value, "url"):
                 output.append('%s <a target="_blank" href="%s">%s</a> <br />%s ' % \
    -                (_('Currently:'), value.url, value, _('Change:')))
    +                (_('Currently:'), escape(value.url), escape(value), _('Change:')))
             output.append(super(AdminFileWidget, self).render(name, value, attrs))
             return mark_safe(u''.join(output))
     
    
  • tests/regressiontests/admin_widgets/tests.py+16 0 modified
    @@ -239,6 +239,22 @@ def test_render(self):
                 '<input type="file" name="test" />',
             )
     
    +    def test_render_escapes_html(self):
    +        class StrangeFieldFile(object):
    +            url = "something?chapter=1&sect=2&copy=3&lang=en"
    +
    +            def __unicode__(self):
    +                return u'''something<div onclick="alert('oops')">.jpg'''
    +
    +        widget = AdminFileWidget()
    +        field = StrangeFieldFile()
    +        output = widget.render('myfile', field)
    +        self.assertFalse(field.url in output)
    +        self.assertTrue(u'href="something?chapter=1&amp;sect=2&amp;copy=3&amp;lang=en"' in output)
    +        self.assertFalse(unicode(field) in output)
    +        self.assertTrue(u'something&lt;div onclick=&quot;alert(&#39;oops&#39;)&quot;&gt;.jpg' in output)
    +
    +
     
     class ForeignKeyRawIdWidgetTest(DjangoTestCase):
         def test_render(self):
    
a9cf3d23724f

[1.2.X] Fixed #14982 -- Ensure that EMPTY_CHANGELIST_VALUE is honored for nullable foreign keys. Thanks to marcob for the report and fix, and to sontek for the test case.

https://github.com/django/djangoRussell Keith-MageeJan 24, 2011via ghsa
3 files changed · +27 3
  • django/contrib/admin/templatetags/admin_list.py+5 1 modified
    @@ -157,7 +157,11 @@ def items_for_result(cl, result, form):
                     if value is None:
                         result_repr = EMPTY_CHANGELIST_VALUE
                     if isinstance(f.rel, models.ManyToOneRel):
    -                    result_repr = escape(getattr(result, f.name))
    +                    field_val = getattr(result, f.name)
    +                    if field_val is None:
    +                        result_repr = EMPTY_CHANGELIST_VALUE
    +                    else:
    +                        result_repr = escape(field_val)
                     else:
                         result_repr = display_for_field(value, f)
                     if isinstance(f, models.DateField) or isinstance(f, models.TimeField):
    
  • tests/regressiontests/admin_changelist/models.py+2 2 modified
    @@ -5,5 +5,5 @@ class Parent(models.Model):
         name = models.CharField(max_length=128)
     
     class Child(models.Model):
    -    parent = models.ForeignKey(Parent, editable=False)
    -    name = models.CharField(max_length=30, blank=True)
    \ No newline at end of file
    +    parent = models.ForeignKey(Parent, editable=False, null=True)
    +    name = models.CharField(max_length=30, blank=True)
    
  • tests/regressiontests/admin_changelist/tests.py+20 0 modified
    @@ -17,6 +17,26 @@ def test_select_related_preserved(self):
                     m.list_select_related, m.list_per_page, m.list_editable, m)
             self.assertEqual(cl.query_set.query.select_related, {'parent': {'name': {}}})
     
    +    def test_result_list_empty_changelist_value(self):
    +        """
    +        Regression test for #14982: EMPTY_CHANGELIST_VALUE should be honored
    +        for relationship fields
    +        """
    +        new_child = Child.objects.create(name='name', parent=None)
    +        request = MockRequest()
    +        m = ChildAdmin(Child, admin.site)
    +        cl = ChangeList(request, Child, m.list_display, m.list_display_links,
    +                m.list_filter, m.date_hierarchy, m.search_fields,
    +                m.list_select_related, m.list_per_page, m.list_editable, m)
    +        cl.formset = None
    +        template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
    +        context = Context({'cl': cl})
    +        table_output = template.render(context)
    +        row_html = '<tbody><tr class="row1"><td><input type="checkbox" class="action-select" value="1" name="_selected_action" /></td><th><a href="1/">name</a></th><td>(None)</td></tr></tbody>'
    +        self.assertFalse(table_output.find(row_html) == -1,
    +            'Failed to find expected row element: %s' % table_output)
    +
    +
         def test_result_list_html(self):
             """
             Verifies that inclusion tag result_list generates a table when with
    
90be6ca20d60

[1.2.X] Fixed #15032 -- Replaced 1.2.X implementation of admin changelist filtering security fix (r15031/r15033) with the one from trunk so another valid filter usage scenario (using model inheritance) is still possible. Thanks rene for reporting this.

https://github.com/django/djangoRamiro MoralesJan 12, 2011via ghsa
3 files changed · +38 3
  • django/contrib/admin/options.py+15 2 modified
    @@ -195,8 +195,21 @@ def lookup_allowed(self, lookup):
     
             # Special case -- foo__id__exact and foo__id queries are implied
             # if foo has been specificially included in the lookup list; so
    -        # drop __id if it is the last part.
    -        if len(parts) > 1 and parts[-1] == self.model._meta.pk.name:
    +        # drop __id if it is the last part. However, first we need to find
    +        # the pk attribute name.
    +        model = self.model
    +        pk_attr_name = None
    +        for part in parts[:-1]:
    +            field, _, _, _ = model._meta.get_field_by_name(part)
    +            if hasattr(field, 'rel'):
    +                model = field.rel.to
    +                pk_attr_name = model._meta.pk.name
    +            elif isinstance(field, RelatedObject):
    +                model = field.model
    +                pk_attr_name = model._meta.pk.name
    +            else:
    +                pk_attr_name = None
    +        if pk_attr_name and len(parts) > 1 and parts[-1] == pk_attr_name:
                 parts.pop()
     
             try:
    
  • tests/regressiontests/admin_views/models.py+12 0 modified
    @@ -588,6 +588,17 @@ class Album(models.Model):
     class AlbumAdmin(admin.ModelAdmin):
         list_filter = ['title']
     
    +class Employee(Person):
    +    code = models.CharField(max_length=20)
    +
    +class WorkHour(models.Model):
    +    datum = models.DateField()
    +    employee = models.ForeignKey(Employee)
    +
    +class WorkHourAdmin(admin.ModelAdmin):
    +    list_display = ('datum', 'employee')
    +    list_filter = ('employee',)
    +
     admin.site.register(Article, ArticleAdmin)
     admin.site.register(CustomArticle, CustomArticleAdmin)
     admin.site.register(Section, save_as=True, inlines=[ArticleInline])
    @@ -619,6 +630,7 @@ class AlbumAdmin(admin.ModelAdmin):
     admin.site.register(PlotDetails)
     admin.site.register(CyclicOne)
     admin.site.register(CyclicTwo)
    +admin.site.register(WorkHour, WorkHourAdmin)
     
     # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
     # That way we cover all four cases:
    
  • tests/regressiontests/admin_views/tests.py+11 1 modified
    @@ -28,7 +28,7 @@
         FooAccount, Gallery, ModelWithStringPrimaryKey, \
         Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast, \
         Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit, \
    -    Category, Post, Plot, FunkyTag
    +    Category, Post, Plot, FunkyTag, WorkHour, Employee
     
     
     class AdminViewBasicTest(TestCase):
    @@ -311,6 +311,16 @@ def test_disallowed_filtering(self):
             except SuspiciousOperation:
                 self.fail("Filters should be allowed if they involve a local field without the need to whitelist them in list_filter or date_hierarchy.")
     
    +        e1 = Employee.objects.create(name='Anonymous', gender=1, age=22, alive=True, code='123')
    +        e2 = Employee.objects.create(name='Visitor', gender=2, age=19, alive=True, code='124')
    +        WorkHour.objects.create(datum=datetime.datetime.now(), employee=e1)
    +        WorkHour.objects.create(datum=datetime.datetime.now(), employee=e2)
    +        response = self.client.get("/test_admin/admin/admin_views/workhour/")
    +        self.assertEqual(response.status_code, 200)
    +        self.assertContains(response, 'employee__person_ptr__exact')
    +        response = self.client.get("/test_admin/admin/admin_views/workhour/?employee__person_ptr__exact=%d" % e1.pk)
    +        self.assertEqual(response.status_code, 200)
    +
     class SaveAsTests(TestCase):
         fixtures = ['admin-views-users.xml','admin-views-person.xml']
     
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

31

News mentions

0

No linked articles in our index yet.