CVE-2015-8310: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Cross-site scripting (XSS) vulnerability in Cherry Music before 0.36.0 allows remote authenticated users to inject arbitrary web script or HTML via the playlistname field when creating a new playlist.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
CVSS v3 base score: 5.4
Published: 2017-03-27T15:59Z
Repository: https://github.com/devsnd/cherrymusic
Language: Python
Files changed: cherrymusicserver/httphandler.py, res/js/playlistmanager.js
Commit date: 2015-11-21 17:04:02 +0100
Commit message: fixes for CVE-2015-8309 (download arbitrary files) and CVE-2015-8309 (XSS vulnerability)

Many thanks to feedersec for checking the security of CherryMusic!

Note to CM users: Both those vulnerabilities only work for logged-in users.

Diff: diff --git a/cherrymusicserver/httphandler.py b/cherrymusicserver/httphandler.py
index 641d805..11aa25c 100644
--- a/cherrymusicserver/httphandler.py
+++ b/cherrymusicserver/httphandler.py
@@ -298,11 +298,15 @@ class HTTPHandler(object):
             uo = self.useroptions.forUser(self.getUserId())
             if not uo.getOptionValue('media.may_download'):
                 return 'not_permitted'
         # make sure nobody tries to escape from basedir
         for f in filelist:
-            if '/../' in f:
+            # don't allow to traverse up in the file system
+            if '/../' in f or f.startswith('../'):
+                return 'invalid_file'
+            # CVE-2015-8309: do not allow absolute file paths
+            if os.path.isabs(f):
                 return 'invalid_file'
         # make sure all files are smaller than maximum download size
         size_limit = cherry.config['media.maximum_download_size']
         try:
             if self.model.file_size_within_limit(filelist, size_limit):
diff --git a/res/js/playlistmanager.js b/res/js/playlistmanager.js
index feb23c9..479381f 100644
--- a/res/js/playlistmanager.js
+++ b/res/js/playlistmanager.js
@@ -560,12 +560,13 @@ PlaylistManager.prototype = {
             var isunsaved = '';
             if(!pl.saved && pl.reason_open !== 'queue'){
                 isunsaved += ' <em>(unsaved)</em>';
             }
 
-
-            pltabs += '<a href="#" onclick="playlistManager.showPlaylist('+pl.id+')">'+isplaying+' '+pl.name+ isunsaved;
+            // fix for CVE-2015-8310
+            var escaped_playlist_name = $("<div>").text(pl.name).html();
+            pltabs += '<a href="#" onclick="playlistManager.showPlaylist('+pl.id+')">'+isplaying+' '+escaped_playlist_name + isunsaved;
             if(pl.closable){
                 pltabs += '<span class="playlist-tab-closer pointer" href="#" onclick="playlistManager.closePlaylist('+pl.id+')">&times;</span>';
             }
             pltabs += '</a></li>';
         }

Vulnerable code:             if '/../' in f:

            pltabs += '<a href="#" onclick="playlistManager.showPlaylist('+pl.id+')">'+isplaying+' '+pl.name+ isunsaved;
Fixed code:             # don't allow to traverse up in the file system
            if '/../' in f or f.startswith('../'):
                return 'invalid_file'
            # CVE-2015-8309: do not allow absolute file paths
            if os.path.isabs(f):
            // fix for CVE-2015-8310
            var escaped_playlist_name = $("<div>").text(pl.name).html();
            pltabs += '<a href="#" onclick="playlistManager.showPlaylist('+pl.id+')">'+isplaying+' '+escaped_playlist_name + isunsaved;