CVE-2015-8309: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') (CWE-22)
value: Directory traversal vulnerability in Cherry Music before 0.36.0 allows remote authenticated users to read arbitrary files via the "value" parameter to "download."
CWE description: The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.
CVSS v3 base score: 4.3
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;