From e8d99ccc2f2e755c574ccc3f6b4cf2dfada3e71b Mon Sep 17 00:00:00 2001 From: Paul Sori Date: Tue, 22 Jan 2019 02:31:03 -0500 Subject: [PATCH] Playlist XSS fix + more efficient playlist retrival code --- modules/db-read/database-public-loki.js | 6 ++--- mstream.js | 2 +- public/js/mstream.js | 32 +++++++++++++++++++------ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/modules/db-read/database-public-loki.js b/modules/db-read/database-public-loki.js index d58a17f..947b989 100644 --- a/modules/db-read/database-public-loki.js +++ b/modules/db-read/database-public-loki.js @@ -233,11 +233,11 @@ exports.setup = function (mstream, program) { const playlists = []; const results = playlistCollection.find({ 'user': { '$eq': username } }); - const store = []; + const store = {}; for (let row of results) { - if (store.indexOf(row.name) === -1) { + if (!store[row.name]) { playlists.push({ name: row.name }); - store.push(row.name); + store[row.name] = true; } } return playlists; diff --git a/mstream.js b/mstream.js index 01cc777..2c8e5d0 100755 --- a/mstream.js +++ b/mstream.js @@ -101,7 +101,7 @@ exports.serveit = function (program) { program.users['mstream-user']['lastfm-password'] = program['lastfm-password'] } - // Fill iin user vpaths + // Fill in user vpaths for (var key in program.folders) { program.users['mstream-user'].vpaths.push(key); } diff --git a/public/js/mstream.js b/public/js/mstream.js index 7f33323..7bb2f5f 100755 --- a/public/js/mstream.js +++ b/public/js/mstream.js @@ -1,3 +1,20 @@ +var entityMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '/': '/', + '`': '`', + '=': '=' +}; + +function escapeHtml (string) { + return String(string).replace(/[&<>"'`=\/]/g, function (s) { + return entityMap[s]; + }); +} + $(document).ready(function () { // Responsive active content $(document).on('click', '.activate-panel-1', function(event) { @@ -308,7 +325,7 @@ $(document).ready(function () { var currentBrowsingList = []; //////////////////////////////// Administrative stuff - // when you click an mp3, add it to the now playling playlist + // when you click an mp3, add it to now playing $("#filelist").on('click', 'div.filez', function () { MSTREAMAPI.addSongWizard($(this).data("file_location"), {}, true); }); @@ -504,7 +521,7 @@ $(document).ready(function () { if (this.type === 'directory') { filelist.push('
' + this.name + '
'); } else if (this.type === 'playlist') { - filelist.push('
' + this.name + '
Delete
'); + filelist.push('
' + escapeHtml(this.name) + '
Delete
'); } else if (this.type === 'album') { if (this.album_art_file) { filelist.push('
' + this.name + '
'); @@ -687,7 +704,8 @@ $(document).ready(function () { // loop through the json array and make an array of corresponding divs var playlists = []; $.each(response, function () { - playlists.push('
' + this.name + '
Delete
'); + console.log() + playlists.push('
' + escapeHtml(this.name) + '
Delete
'); this.type = 'playlist'; currentBrowsingList.push(this); VUEPLAYER.playlists.push(this); @@ -699,7 +717,7 @@ $(document).ready(function () { // delete playlist $("#filelist").on('click', '.deletePlaylist', function () { - var playlistname = $(this).data('playlistname'); + var playlistname = decodeURIComponent($(this).data('playlistname')); iziToast.question({ timeout: 10000, @@ -717,7 +735,7 @@ $(document).ready(function () { if (error !== false) { return boilerplateFailure(response, error); } - $('div[data-playlistname="'+playlistname+'"]').remove(); + $('div[data-playlistname="'+encodeURIComponent(playlistname)+'"]').remove(); }); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true], @@ -740,13 +758,13 @@ $(document).ready(function () { // load up a playlist $("#filelist").on('click', '.playlistz', function () { - var playlistname = $(this).data('playlistname'); + var playlistname = decodeURIComponent($(this).data('playlistname')); var name = $(this).html(); $('.directoryName').html('Playlist: ' + name); programState.push({ state: 'playlist', - name: name + name: playlistname }) MSTREAMAPI.loadPlaylist(playlistname, function (response, error) {