From 99ff7f5c0878f83eee96edc544cfa578f72ea653 Mon Sep 17 00:00:00 2001 From: Brandon Byars Date: Sun, 27 Sep 2020 14:54:16 -0500 Subject: [PATCH] Fixed path traversal issue https://github.com/bbyars/mountebank/issues/567 --- src/controllers/feedController.js | 7 ++++++- test/controllers/feedControllerTest.js | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 test/controllers/feedControllerTest.js diff --git a/src/controllers/feedController.js b/src/controllers/feedController.js index 9a30c159a..2036b16ee 100644 --- a/src/controllers/feedController.js +++ b/src/controllers/feedController.js @@ -24,6 +24,11 @@ function create (releases, options) { return path.join(__dirname, '/../views/', releaseViewFor(version)); }; + function versionInWhitelist (version) { + // Prevent path traversal attack like v2.3.0%2f..%2f..%2f_header + return feedReleases.some(release => version.toLowerCase() === release.version); + } + /** * The function that responds to GET /feed * @memberOf module:controllers/feedController# @@ -86,7 +91,7 @@ function create (releases, options) { releaseVersion: version.replace('v', '') }; - if (fs.existsSync(releaseFilenameFor(version))) { + if (versionInWhitelist(version) && fs.existsSync(releaseFilenameFor(version))) { response.render('_header', config, (headerError, header) => { if (headerError) { throw headerError; } response.render(releaseViewFor(version), config, (bodyError, body) => { diff --git a/test/controllers/feedControllerTest.js b/test/controllers/feedControllerTest.js new file mode 100644 index 000000000..0a9a81f22 --- /dev/null +++ b/test/controllers/feedControllerTest.js @@ -0,0 +1,23 @@ +'use strict'; + +const Controller = require('../../src/controllers/feedController'), + assert = require('assert'), + mock = require('../mock').mock; + +describe('feedController', function () { + describe('#getRelease', function () { + it('should prevent path traversal attacks', function () { + const response = { status: mock().returns({ send: mock() }) }, + releases = [{ version: 'v2.3.0', date: '2020-09-07' }], + controller = Controller.create(releases, { heroku: false }), + request = { + headers: { host: 'localhost' }, + params: { version: 'v2.3.0%2f..%2f..%2f_header' } + }; + + controller.getRelease(request, response); + + assert.ok(response.status.wasCalledWith(404)); + }); + }); +});