From 31b4bacf81f45dbdddfa7d353d84c02e26e52eb3 Mon Sep 17 00:00:00 2001 From: Julie Pichon Date: Thu, 22 May 2014 16:45:03 +0100 Subject: [PATCH] Fix multiple Cross-Site Scripting (XSS) vulnerabilities. * Ensure user emails are properly escaped User emails in the Users and Groups panel are being passed through the urlize filter to transform them into clickable links. However, urlize expects input to be already escaped and safe. We should make sure to escape the strings first as email addresses are not validated and can contain any type of string. Closes-Bug: #1320235 * Ensure network names are properly escaped in the Launch Instance menu Closes-Bug: #1322197 * Escape the URLs generated for the Horizon tables When generating the Horizon tables, there was an assumption that only the anchor text needed to be escaped. However some URLs are generated based on user-provided data and should be escaped as well. Also escape the link attributes for good measure. Closes-Bug: #1308727 Change-Id: Ic8a92e69f66c2d265a802f350e30f091181aa42e --- horizon/static/horizon/js/horizon.instances.js | 5 ++++- horizon/tables/base.py | 4 +++- openstack_dashboard/dashboards/admin/groups/tables.py | 3 ++- openstack_dashboard/dashboards/admin/users/tables.py | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/horizon/static/horizon/js/horizon.instances.js b/horizon/static/horizon/js/horizon.instances.js index 6ffc8ee..3384d53 100644 --- a/horizon/static/horizon/js/horizon.instances.js +++ b/horizon/static/horizon/js/horizon.instances.js @@ -52,7 +52,10 @@ horizon.instances = { var $this = $(this); var $input = $this.children("input"); var network_property = { - name:$this.text().replace(/^\s+/,""), + // The network name is already safely escaped, therefore use + // html() instead of text() as text() would result in the html + // entities being unescaped. + name:$this.html().replace(/^\s+/,""), id:$input.attr("id"), value:$input.attr("value") }; diff --git a/horizon/tables/base.py b/horizon/tables/base.py index d3bad41..bed3940 100644 --- a/horizon/tables/base.py +++ b/horizon/tables/base.py @@ -674,7 +674,9 @@ class Cell(html.HTMLElement): link_classes = ' '.join(self.column.link_classes) # Escape the data inside while allowing our HTML to render data = mark_safe('%s' % - (self.url, link_classes, escape(unicode(data)))) + (escape(self.url), + escape(link_classes), + escape(unicode(data)))) return data @property diff --git a/openstack_dashboard/dashboards/admin/groups/tables.py b/openstack_dashboard/dashboards/admin/groups/tables.py index ba24f3d..1bb6004 100644 --- a/openstack_dashboard/dashboards/admin/groups/tables.py +++ b/openstack_dashboard/dashboards/admin/groups/tables.py @@ -159,7 +159,8 @@ class AddMembersLink(tables.LinkAction): class UsersTable(tables.DataTable): name = tables.Column('name', verbose_name=_('User Name')) email = tables.Column('email', verbose_name=_('Email'), - filters=[defaultfilters.urlize]) + filters=[defaultfilters.escape, + defaultfilters.urlize]) id = tables.Column('id', verbose_name=_('User ID')) enabled = tables.Column('enabled', verbose_name=_('Enabled'), status=True, diff --git a/openstack_dashboard/dashboards/admin/users/tables.py b/openstack_dashboard/dashboards/admin/users/tables.py index b2032c4..9c6dc04 100644 --- a/openstack_dashboard/dashboards/admin/users/tables.py +++ b/openstack_dashboard/dashboards/admin/users/tables.py @@ -131,7 +131,9 @@ class UsersTable(tables.DataTable): email = tables.Column('email', verbose_name=_('Email'), filters=(lambda v: defaultfilters .default_if_none(v, ""), - defaultfilters.urlize)) + defaultfilters.escape, + defaultfilters.urlize) + ) # Default tenant is not returned from Keystone currently. #default_tenant = tables.Column('default_tenant', # verbose_name=_('Default Project')) -- 1.8.3.1