From 1cecc12e23fd6ab000b9d05307ee2e2521687a84 Mon Sep 17 00:00:00 2001 From: Wing Ho Date: Fri, 31 May 2019 18:00:27 +1000 Subject: [PATCH 1/7] serve prerendered if available --- lib/makeserver.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/makeserver.js b/lib/makeserver.js index e5f71654..6d420e5e 100644 --- a/lib/makeserver.js +++ b/lib/makeserver.js @@ -146,6 +146,19 @@ module.exports = function(options) { initPaths.push(path.join(options.wwwroot, 'init')); } + app.get('*', function (request, response, next) { + const prerendered = path.resolve(options.wwwroot, request.path, 'index.html'); + // const fallbackIndex = path.resolve(options.wwwroot, 'index.html'); + if (fs.existsSync(prerendered)) { + response.sendFile(prerendered); + } else { + next(); + } + // else { + // response.sendFile(fallbackIndex); + // } + }); + app.use('/init', require('./controllers/initfile')(initPaths, error404, options.configDir)); var feedbackService = require('./controllers/feedback')(options.settings.feedback); From d21cb38f51aa5d093ecb24e025d0085175c62bdc Mon Sep 17 00:00:00 2001 From: Wing Ho Date: Thu, 6 Jun 2019 11:23:45 +1000 Subject: [PATCH 2/7] Really serve prerendered Also now resolves catalog routes with base index.html --- lib/makeserver.js | 24 ++++++++++++++---------- package.json | 3 ++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/makeserver.js b/lib/makeserver.js index 6d420e5e..c34b8795 100644 --- a/lib/makeserver.js +++ b/lib/makeserver.js @@ -8,6 +8,7 @@ var cors = require('cors'); var exists = require('./exists'); var basicAuth = require('basic-auth'); var fs = require('fs'); +var URI = require("urijs"); var ExpressBrute = require('express-brute'); /* Creates and returns a single express server. */ @@ -142,23 +143,26 @@ module.exports = function(options) { var error500 = errorPage.error500(show500, options.wwwroot); var initPaths = options.settings.initPaths || []; - if (serveWwwRoot) { - initPaths.push(path.join(options.wwwroot, 'init')); - } + // Serve up prerendered pages if they exist for a given route + app.get('*', function (req, res, next) { + const decodedPath = URI.decode(req.path); + const prerendered = path.resolve(options.wwwroot, `prerendered/${decodedPath}`, 'index.html'); - app.get('*', function (request, response, next) { - const prerendered = path.resolve(options.wwwroot, request.path, 'index.html'); - // const fallbackIndex = path.resolve(options.wwwroot, 'index.html'); if (fs.existsSync(prerendered)) { - response.sendFile(prerendered); + res.sendFile(prerendered); + // Other /catalog/ routes should at least return index.html, in case of unresolved pathing/id + } else if (decodedPath.substr(0,9) === "/catalog/") { + res.sendFile(options.wwwroot + '/index.html'); } else { + // For now, don't resolve remaining app urls SPA-style with all-routes-200-index.html next(); } - // else { - // response.sendFile(fallbackIndex); - // } }); + if (serveWwwRoot) { + initPaths.push(path.join(options.wwwroot, 'init')); + } + app.use('/init', require('./controllers/initfile')(initPaths, error404, options.configDir)); var feedbackService = require('./controllers/feedback')(options.settings.feedback); diff --git a/package.json b/package.json index d0ee3a36..7d5dad04 100644 --- a/package.json +++ b/package.json @@ -44,12 +44,13 @@ "json5": "^2.1.0", "morgan": "^1.7.0", "pm2": "^3.2.2", - "terriajs-ogr2ogr": "^1.0.0", "proj4": "^2.3.12", "proj4js-defs": "0.0.1", "range_check": "^1.4.0", "request": "^2.67.0", "request-promise": "^4.0.1", + "terriajs-ogr2ogr": "^1.0.0", + "urijs": "^1.18.12", "when": "^3.7.7", "yargs": "^13.2.4" }, From ff186a352051be386cfd83e311a61e06cbc350ea Mon Sep 17 00:00:00 2001 From: Wing Ho Date: Thu, 6 Jun 2019 12:37:24 +1000 Subject: [PATCH 3/7] Update baseHref example --- serverconfig.json.example | 3 +++ 1 file changed, 3 insertions(+) diff --git a/serverconfig.json.example b/serverconfig.json.example index 0d79ab7f..b244247a 100644 --- a/serverconfig.json.example +++ b/serverconfig.json.example @@ -2,6 +2,9 @@ // Port to listen on. Overriden by the --port command line setting. port: 3001, + // If you are serving TerriaMap from a directory, specify the path to it here + baseHref: "/", + // List of domains which the server is willing to proxy for. Subdomains are included automatically. allowProxyFor : [ "nicta.com.au", From 3948c95aa4380fda3b84ae17f9d2803d5f0b0474 Mon Sep 17 00:00:00 2001 From: Wing Ho Date: Fri, 21 Jun 2019 17:57:52 +1000 Subject: [PATCH 4/7] Update serverconfig.json docs --- serverconfig.json.example | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/serverconfig.json.example b/serverconfig.json.example index b244247a..61034f7b 100644 --- a/serverconfig.json.example +++ b/serverconfig.json.example @@ -2,7 +2,8 @@ // Port to listen on. Overriden by the --port command line setting. port: 3001, - // If you are serving TerriaMap from a directory, specify the path to it here + // If you are serving TerriaMap from a directory, specify the path to it here, + // otherwise leave it as '/' for root paths baseHref: "/", // List of domains which the server is willing to proxy for. Subdomains are included automatically. From 2c7b7d9170af1a14c9ee00701e10d6a6693694a1 Mon Sep 17 00:00:00 2001 From: Wing Ho Date: Tue, 3 Dec 2019 16:45:24 +1100 Subject: [PATCH 5/7] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ea14fbb5..c183eed1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "terriajs-server", - "version": "3.1.0", + "version": "3.1.0-new-routing", "description": "NodeJS server for TerriaJS, consisting of a CORS proxy, proj4 CRS lookup service, ogr2ogr conversion service, and express static server.", "engineStrict": true, "engines": { From fa10d232254752592857470cf4b99048a4d16ca0 Mon Sep 17 00:00:00 2001 From: Stephen Davies Date: Thu, 2 Dec 2021 22:58:49 +1100 Subject: [PATCH 6/7] Replace URI.decode with decodeURIComponent, which is identical --- lib/makeserver.js | 3 +-- package.json | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/makeserver.js b/lib/makeserver.js index 810c7156..6b727b0f 100644 --- a/lib/makeserver.js +++ b/lib/makeserver.js @@ -8,7 +8,6 @@ var cors = require('cors'); var exists = require('./exists'); var basicAuth = require('basic-auth'); var fs = require('fs'); -var URI = require("urijs"); var ExpressBrute = require('express-brute'); /* Creates and returns a single express server. */ @@ -150,7 +149,7 @@ module.exports = function(options) { // Serve up prerendered pages if they exist for a given route app.get('*', function (req, res, next) { - const decodedPath = URI.decode(req.path); + const decodedPath = decodeURIComponent(req.path); const prerendered = path.resolve(options.wwwroot, `prerendered/${decodedPath}`, 'index.html'); if (fs.existsSync(prerendered)) { diff --git a/package.json b/package.json index f3e0df85..3005f04b 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,6 @@ "request": "^2.67.0", "request-promise": "^4.0.1", "terriajs-ogr2ogr": "^1.0.0", - "urijs": "^1.18.12", "when": "^3.7.7", "yargs": "^13.2.4" }, From 3e82c04d54613b303ab3f1c37b543fe7e8a555a2 Mon Sep 17 00:00:00 2001 From: Stephen Davies Date: Mon, 28 Feb 2022 04:20:17 +1100 Subject: [PATCH 7/7] Prevent path traversal --- lib/makeserver.js | 5 +++++ terriajs-server.js | 0 2 files changed, 5 insertions(+) mode change 100644 => 100755 terriajs-server.js diff --git a/lib/makeserver.js b/lib/makeserver.js index 6b727b0f..5baba16b 100644 --- a/lib/makeserver.js +++ b/lib/makeserver.js @@ -151,6 +151,11 @@ module.exports = function(options) { app.get('*', function (req, res, next) { const decodedPath = decodeURIComponent(req.path); const prerendered = path.resolve(options.wwwroot, `prerendered/${decodedPath}`, 'index.html'); + if (!prerendered.startsWith(path.resolve(options.wwwroot, 'prerendered/') + '/')) { + // Path traversal attack (using e.g. ..%2F) + next(); + return; + } if (fs.existsSync(prerendered)) { res.sendFile(prerendered); diff --git a/terriajs-server.js b/terriajs-server.js old mode 100644 new mode 100755