changeset 5219:c9cfaeb1cdfe stable

tooltips: fix unsafe insertion of userdata into the DOM as html This fixes js injection in the admin journal ... and probably also in other places. Tooltips are used both with hardcoded strings (which is safe and simple) and with user provided strings wrapped in html formatting (which requires careful escaping before being put into the DOM as html). The templating will automatically take care of one level of escaping, but here it requires two levels to do it correctly ... and that was not always done correctly. Instead, by default, just insert it into the DOM as text, not as html. The few places where we know the tooltip contains safe html are handled specially - the element is given the safe-html-title class. That is the case in file annotation and in display of tip revision in repo lists.
author Mads Kiilerich <madski@unity3d.com>
date Tue, 07 Jul 2015 02:09:35 +0200
parents c0da0ef508da
children 9d87b8d5ba00
files kallithea/lib/helpers.py kallithea/public/js/base.js kallithea/templates/data_table/_dt_elements.html
diffstat 3 files changed, 14 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/lib/helpers.py	Tue Jul 07 02:09:35 2015 +0200
+++ b/kallithea/lib/helpers.py	Tue Jul 07 02:09:35 2015 +0200
@@ -352,9 +352,9 @@
     def url_func(repo_name):
 
         def _url_func(changeset):
-            author = changeset.author
+            author = escape(changeset.author)
             date = changeset.date
-            message = tooltip(changeset.message)
+            message = escape(changeset.message)
 
             tooltip_html = ("<div style='font-size:0.8em'><b>Author:</b>"
                             " %s<br/><b>Date:</b> %s</b><br/><b>Message:"
@@ -367,7 +367,7 @@
                     url('changeset_home', repo_name=repo_name,
                         revision=changeset.raw_id),
                     style=get_color_string(changeset.raw_id),
-                    class_='tooltip',
+                    class_='tooltip safe-html-title',
                     title=tooltip_html
                   )
 
--- a/kallithea/public/js/base.js	Tue Jul 07 02:09:35 2015 +0200
+++ b/kallithea/public/js/base.js	Tue Jul 07 02:09:35 2015 +0200
@@ -510,25 +510,31 @@
     _activate_tooltip($('.tooltip'));
 };
 
-var _show_tooltip = function(e, tipText){
+var _show_tooltip = function(e, tipText, safe){
     e.stopImmediatePropagation();
     var el = e.currentTarget;
+    var $el = $(el);
     if(tipText){
         // just use it
     } else if(el.tagName.toLowerCase() === 'img'){
         tipText = el.alt ? el.alt : '';
     } else {
         tipText = el.title ? el.title : '';
+        safe = safe || $el.hasClass("safe-html-title");
     }
 
     if(tipText !== ''){
         // save org title
-        $(el).attr('tt_title', tipText);
+        $el.attr('tt_title', tipText);
         // reset title to not show org tooltips
-        $(el).attr('title', '');
+        $el.attr('title', '');
 
         var $tipBox = $('#tip-box');
-        $tipBox.html(tipText);
+        if (safe) {
+            $tipBox.html(tipText);
+        } else {
+            $tipBox.text(tipText);
+        }
         $tipBox.css('display', 'block');
     }
 };
--- a/kallithea/templates/data_table/_dt_elements.html	Tue Jul 07 02:09:35 2015 +0200
+++ b/kallithea/templates/data_table/_dt_elements.html	Tue Jul 07 02:09:35 2015 +0200
@@ -93,7 +93,7 @@
 <%def name="revision(name,rev,tip,author,last_msg)">
   <div>
   %if rev >= 0:
-      <a title="${h.tooltip('%s:\n\n%s' % (author,last_msg))}" class="tooltip revision-link" href="${h.url('changeset_home',repo_name=name,revision=tip)}">${'r%s:%s' % (rev,h.short_id(tip))}</a>
+      <a title="${h.tooltip('%s:\n\n%s' % (author,last_msg))}" class="tooltip revision-link safe-html-title" href="${h.url('changeset_home',repo_name=name,revision=tip)}">${'r%s:%s' % (rev,h.short_id(tip))}</a>
   %else:
       ${_('No changesets yet')}
   %endif