diff --git a/server/routers/StaticRouter.js b/server/routers/StaticRouter.js index 555b6a8d..eb8b424f 100644 --- a/server/routers/StaticRouter.js +++ b/server/routers/StaticRouter.js @@ -18,7 +18,22 @@ class StaticRouter { const item = this.db.libraryItems.find(ab => ab.id === req.params.id) if (!item) return res.status(404).send('Item not found with id ' + req.params.id) - const remainingPath = req.params['0'] + // Replace backslashes with forward slashes + const remainingPath = req.params['0'].replace(/\\/g, '/') + + // Check user has access to this library item + if (!req.user.checkCanAccessLibraryItem(item)) { + Logger.error(`[StaticRouter] User attempted to access library item file without access ${remainingPath}`, req.user) + return res.sendStatus(403) + } + + // Prevent path traversal + // e.g. ../../etc/passwd + if (/\/?\.?\.\//.test(remainingPath)) { + Logger.error(`[StaticRouter] Invalid path to get library item file "${remainingPath}"`) + return res.sendStatus(403) + } + const fullPath = item.isFile ? item.path : Path.join(item.path, remainingPath) // Allow reverse proxy to serve files directly @@ -28,7 +43,7 @@ class StaticRouter { return res.status(204).header({ 'X-Accel-Redirect': global.XAccel + fullPath }).send() } - var opts = {} + let opts = {} // Express does not set the correct mimetype for m4b files so use our defined mimetypes if available const audioMimeType = getAudioMimeTypeFromExtname(Path.extname(fullPath))