Changeset - a8d873e9cab0
[Not reviewed]
default
0 1 0
Thomas De Schampheleire - 7 years ago 2019-02-26 21:27:42
thomas.de_schampheleire@nokia.com
compare: prevent XSS due to unescaped branch/tag/bookmark names

In the revision selection dropdown of the 'Compare' functionality, the
branch/tag/bookmark names were not correctly escaped.

This means that if an attacker is able to push a branch/tag/bookmark
containing HTML/JavaScript in its name, then that code would be evaluated.
This is a cross-site scripting (XSS) vulnerability.

Fix the problem by correctly escaping the branch/tag/bookmarks.
1 file changed with 1 insertions and 1 deletions:
0 comments (0 inline, 0 general)
kallithea/templates/compare/compare_diff.html
Show inline comments
 
@@ -86,49 +86,49 @@ ${self.repo_context_bar('changelog')}
 
    %endif
 

	
 
    %if not c.compare_home:
 
        ## diff block
 
        <%namespace name="diff_block" file="/changeset/diff_block.html"/>
 
        ${diff_block.diff_block_js()}
 
        ${diff_block.diff_block(c.a_repo.repo_name, c.a_ref_type, c.a_ref_name, c.a_rev,
 
                                c.cs_repo.repo_name, c.cs_ref_type, c.cs_ref_name, c.cs_rev, c.file_diff_data)}
 
        % if c.limited_diff:
 
          <h4>${_('Changeset was too big and was cut off...')} <a href="${h.url.current(fulldiff=1, **request.GET.mixed())}">${_('Show full diff')}</a></h4>
 
        % endif
 
    %endif
 
    </div>
 

	
 
</div>
 
    <script type="text/javascript">
 

	
 
   $(document).ready(function(){
 
    var cache = {};
 

	
 
    function make_revision_dropdown(css_selector, repo_name, ref_name, cache_key) {
 
      $(css_selector).select2({
 
        placeholder: '{0}@{1}'.format(repo_name, ref_name || ${h.jshtml(_('Select changeset'))}),
 
        formatSelection: function(obj){
 
            return '{0}@{1}'.format(repo_name, obj.text);
 
            return '{0}@{1}'.format(repo_name, obj.text).html_escape();
 
        },
 
        dropdownAutoWidth: true,
 
        maxResults: 50,
 
        query: function(query){
 
          var key = cache_key;
 
          var cached = cache[key] ;
 
          if(cached) {
 
            var data = {results: []};
 
            var queryLower = query.term.toLowerCase();
 
            //filter results
 
            $.each(cached.results, function(){
 
                var section = this.text;
 
                var children = [];
 
                $.each(this.children, function(){
 
                    if(children.length < 50 ?
 
                       ((queryLower.length == 0) || (this.text.toLowerCase().indexOf(queryLower) >= 0)) :
 
                       ((queryLower.length != 0) && (this.text.toLowerCase().indexOf(queryLower) == 0))) {
 
                        children.push(this);
 
                    }
 
                });
 
                children = branchSort(children, undefined, query)
 
                data.results.push({'text': section, 'children': children});
 
            });
 
            //push the typed in changeset
0 comments (0 inline, 0 general)