From 80d4ac024f18c4b4d8e5d0a70bd37e1243b5337e Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 13 May 2020 08:42:47 -0400 Subject: [PATCH 1/6] Move "app.disable('x-powered-by')" into the auth middleware --- app.js | 3 +-- app/auth.js | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app.js b/app.js index b2a79ff96..d0cc6028d 100755 --- a/app.js +++ b/app.js @@ -73,8 +73,7 @@ app.set('view engine', 'pug'); // basic http authentication if (process.env.BTCEXP_BASIC_AUTH_PASSWORD) { - app.disable('x-powered-by'); - app.use(auth(process.env.BTCEXP_BASIC_AUTH_PASSWORD)); + app.use(auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD)); } // uncomment after placing your favicon in /public diff --git a/app/auth.js b/app/auth.js index 9aedb7f9d..2321fac1e 100644 --- a/app/auth.js +++ b/app/auth.js @@ -1,6 +1,8 @@ var basicAuth = require('basic-auth'); -module.exports = pass => (req, res, next) => { +module.exports = (app, pass) => (req, res, next) => { + app.disable('x-powered-by'); + var cred = basicAuth(req); if (cred && cred.pass === pass) { From 92eea41aade28e6bf5fe0fd58ac7d3c5c53e7c52 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 13 May 2020 08:43:30 -0400 Subject: [PATCH 2/6] Remove all basic auth from app.js --- app.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app.js b/app.js index d0cc6028d..f0a9e2278 100755 --- a/app.js +++ b/app.js @@ -46,7 +46,6 @@ var qrcode = require("qrcode"); var addressApi = require("./app/api/addressApi.js"); var electrumAddressApi = require("./app/api/electrumAddressApi.js"); var coreApi = require("./app/api/coreApi.js"); -var auth = require('./app/auth.js'); var marked = require("marked"); var package_json = require('./package.json'); @@ -71,11 +70,6 @@ app.engine('pug', (path, options, fn) => { app.set('view engine', 'pug'); -// basic http authentication -if (process.env.BTCEXP_BASIC_AUTH_PASSWORD) { - app.use(auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD)); -} - // uncomment after placing your favicon in /public //app.use(favicon(__dirname + '/public/favicon.ico')); //app.use(logger('dev')); From cc33ff1f1cd25dd4f845c4a23e8f2b5334e94b11 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 13 May 2020 08:45:11 -0400 Subject: [PATCH 3/6] Wrap the baseActionsRouter export in a function that takes an "app" parameter --- app.js | 2 +- routes/baseActionsRouter.js | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app.js b/app.js index f0a9e2278..386835383 100755 --- a/app.js +++ b/app.js @@ -587,7 +587,7 @@ app.use(csurf(), (req, res, next) => { next(); }); -app.use('/', baseActionsRouter); +app.use('/', baseActionsRouter(app)); app.use('/api/', apiActionsRouter); app.use('/snippet/', snippetActionsRouter); diff --git a/routes/baseActionsRouter.js b/routes/baseActionsRouter.js index 037dd8f3e..b14abc3ad 100644 --- a/routes/baseActionsRouter.js +++ b/routes/baseActionsRouter.js @@ -26,6 +26,8 @@ const v8 = require('v8'); const forceCsrf = csurf({ ignoreMethods: [] }); +const routerExport = app => { + router.get("/", function(req, res, next) { if (req.session.host == null || req.session.host.trim() == "") { if (req.cookies['rpc-host']) { @@ -1523,4 +1525,8 @@ router.get("/fun", function(req, res, next) { next(); }); -module.exports = router; +return router + +} + +module.exports = routerExport; From 6bd3630bfaede762d444e829aa01c56c4cffbf1e Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 13 May 2020 08:49:26 -0400 Subject: [PATCH 4/6] Inject the auth middleware on just the RPC routes that require it --- routes/baseActionsRouter.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/routes/baseActionsRouter.js b/routes/baseActionsRouter.js index b14abc3ad..5dd20d874 100644 --- a/routes/baseActionsRouter.js +++ b/routes/baseActionsRouter.js @@ -21,6 +21,7 @@ var config = require("./../app/config.js"); var coreApi = require("./../app/api/coreApi.js"); var addressApi = require("./../app/api/addressApi.js"); var rpcApi = require("./../app/api/rpcApi.js"); +var auth = require('./../app/auth.js'); const v8 = require('v8'); @@ -1169,7 +1170,7 @@ router.get("/address/:address", function(req, res, next) { }); }); -router.get("/rpc-terminal", function(req, res, next) { +router.get("/rpc-terminal", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD), function(req, res, next) { if (!config.demoSite && !req.authenticated) { res.send("RPC Terminal / Browser require authentication. Set an authentication password via the 'BTCEXP_BASIC_AUTH_PASSWORD' environment variable (see .env-sample file for more info)."); @@ -1183,7 +1184,7 @@ router.get("/rpc-terminal", function(req, res, next) { next(); }); -router.post("/rpc-terminal", function(req, res, next) { +router.post("/rpc-terminal", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD), function(req, res, next) { if (!config.demoSite && !req.authenticated) { res.send("RPC Terminal / Browser require authentication. Set an authentication password via the 'BTCEXP_BASIC_AUTH_PASSWORD' environment variable (see .env-sample file for more info)."); @@ -1246,7 +1247,7 @@ router.post("/rpc-terminal", function(req, res, next) { }); }); -router.get("/rpc-browser", function(req, res, next) { +router.get("/rpc-browser", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD), function(req, res, next) { if (!config.demoSite && !req.authenticated) { res.send("RPC Terminal / Browser require authentication. Set an authentication password via the 'BTCEXP_BASIC_AUTH_PASSWORD' environment variable (see .env-sample file for more info)."); From 5a5f5daf3f8dc63d811dcec454ef548880e8bfc2 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 13 May 2020 08:52:24 -0400 Subject: [PATCH 5/6] Pass a "demo" parameter into auth, to selectively override auth if site is in demo mode --- app/auth.js | 4 +++- routes/baseActionsRouter.js | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/app/auth.js b/app/auth.js index 2321fac1e..8042c5fa5 100644 --- a/app/auth.js +++ b/app/auth.js @@ -1,6 +1,8 @@ var basicAuth = require('basic-auth'); -module.exports = (app, pass) => (req, res, next) => { +module.exports = (app, pass, demo = false) => (req, res, next) => { + if (demo) return next(); + app.disable('x-powered-by'); var cred = basicAuth(req); diff --git a/routes/baseActionsRouter.js b/routes/baseActionsRouter.js index 5dd20d874..850033a27 100644 --- a/routes/baseActionsRouter.js +++ b/routes/baseActionsRouter.js @@ -1170,8 +1170,8 @@ router.get("/address/:address", function(req, res, next) { }); }); -router.get("/rpc-terminal", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD), function(req, res, next) { - if (!config.demoSite && !req.authenticated) { +router.get("/rpc-terminal", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD, config.demoSite), function(req, res, next) { + if (!req.authenticated) { res.send("RPC Terminal / Browser require authentication. Set an authentication password via the 'BTCEXP_BASIC_AUTH_PASSWORD' environment variable (see .env-sample file for more info)."); next(); @@ -1184,8 +1184,8 @@ router.get("/rpc-terminal", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD), f next(); }); -router.post("/rpc-terminal", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD), function(req, res, next) { - if (!config.demoSite && !req.authenticated) { +router.post("/rpc-terminal", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD, config.demoSite), function(req, res, next) { + if (!req.authenticated) { res.send("RPC Terminal / Browser require authentication. Set an authentication password via the 'BTCEXP_BASIC_AUTH_PASSWORD' environment variable (see .env-sample file for more info)."); next(); @@ -1247,8 +1247,8 @@ router.post("/rpc-terminal", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD), }); }); -router.get("/rpc-browser", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD), function(req, res, next) { - if (!config.demoSite && !req.authenticated) { +router.get("/rpc-browser", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD, config.demoSite), function(req, res, next) { + if (!req.authenticated) { res.send("RPC Terminal / Browser require authentication. Set an authentication password via the 'BTCEXP_BASIC_AUTH_PASSWORD' environment variable (see .env-sample file for more info)."); next(); From 7937a7ef93e4128a9cfc5a2fe47dba57f8d69bee Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 13 May 2020 09:04:15 -0400 Subject: [PATCH 6/6] If no password is set and user tries to access protected routes, throw that message inside the auth middleware --- app/auth.js | 1 + routes/baseActionsRouter.js | 24 ------------------------ 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/app/auth.js b/app/auth.js index 8042c5fa5..af7d65361 100644 --- a/app/auth.js +++ b/app/auth.js @@ -2,6 +2,7 @@ var basicAuth = require('basic-auth'); module.exports = (app, pass, demo = false) => (req, res, next) => { if (demo) return next(); + if (!pass) return res.status(401).send("This section of the site requires authentication. Set an authentication password via the 'BTCEXP_BASIC_AUTH_PASSWORD' environment variable (see .env-sample file for more info)."); app.disable('x-powered-by'); diff --git a/routes/baseActionsRouter.js b/routes/baseActionsRouter.js index 850033a27..af0d21c5f 100644 --- a/routes/baseActionsRouter.js +++ b/routes/baseActionsRouter.js @@ -1171,28 +1171,12 @@ router.get("/address/:address", function(req, res, next) { }); router.get("/rpc-terminal", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD, config.demoSite), function(req, res, next) { - if (!req.authenticated) { - res.send("RPC Terminal / Browser require authentication. Set an authentication password via the 'BTCEXP_BASIC_AUTH_PASSWORD' environment variable (see .env-sample file for more info)."); - - next(); - - return; - } - res.render("terminal"); next(); }); router.post("/rpc-terminal", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD, config.demoSite), function(req, res, next) { - if (!req.authenticated) { - res.send("RPC Terminal / Browser require authentication. Set an authentication password via the 'BTCEXP_BASIC_AUTH_PASSWORD' environment variable (see .env-sample file for more info)."); - - next(); - - return; - } - var params = req.body.cmd.trim().split(/\s+/); var cmd = params.shift(); var parsedParams = []; @@ -1248,14 +1232,6 @@ router.post("/rpc-terminal", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD, c }); router.get("/rpc-browser", auth(app, process.env.BTCEXP_BASIC_AUTH_PASSWORD, config.demoSite), function(req, res, next) { - if (!req.authenticated) { - res.send("RPC Terminal / Browser require authentication. Set an authentication password via the 'BTCEXP_BASIC_AUTH_PASSWORD' environment variable (see .env-sample file for more info)."); - - next(); - - return; - } - coreApi.getHelp().then(function(result) { res.locals.gethelp = result;