express-status-monitor icon indicating copy to clipboard operation
express-status-monitor copied to clipboard

Securing endpoint not working

Open mayeaux opened this issue 6 years ago • 3 comments

I'm trying to secure the endpoint like such:

const statusMonitor = require('express-status-monitor')();
app.use(statusMonitor);
app.get('/status', function(req, res, next){
  console.log('running');
}, passportConfig.isAuthorized, statusMonitor.pageRoute)

I have a mind to think that this doesn't work, I've tested locally a few ways and it will always resolve when hitting /status and then not run the authentication middleware.

mayeaux avatar Oct 17 '17 22:10 mayeaux

I had the same issue @mayeaux, and was going to propose something like the following pattern, which I'm currently using:

  1. Configure express-status monitor in a helper file (e.g. helpers/statusMonitor.js):
const config = {
  path: '_status',
};

const statusMonitor = require('express-status-monitor')(config);

module.exports = statusMonitor;

The underscore in the path value makes it invalid (i.e. express fails silently), which enables you to handle it elsewhere (see 3 below). Should we add a better way to disable the default path @RafalWilinski / @mattiaerre?

  1. Pass the helper to your app in app.js:
app.use(require('path/to/helpers/statusMonitor'));
  1. In the router, or wherever you want to handle authentication (i.e. a controller), do something like this (example uses passport and connect-flash):
const express = require('express');
const router = express.Router();
const statusMonitor = require('path/to/helpers/statusMonitor');

router.get('/status', (req, res) => {
  if(req.isAuthenticated()) {
      statusMonitor.pageRoute(req, res);
    } else {
      req.flash('error', 'Access denied.');
      res.redirect('/');
    }
});

colinrobertbrooks avatar Oct 18 '17 12:10 colinrobertbrooks

Hello, I found a working solution using http-auth,

const auth = require('http-auth');
const statusMonitor = require('express-status-monitor')({ path: '' });

const basic = auth.basic({realm: 'Monitor Area'}, function(user, pass, callback) {
  callback(user === 'username' && pass === 'password');
});

app.use(statusMonitor.middleware); // use the "middleware only" property to manage websockets
app.get('/status', basic.check(statusMonitor.pageRoute)); // use the pageRoute property to serve the dashboard html page

This solution was found in https://openbase.com/js/express-status-monitor

kurtobando avatar Mar 11 '21 10:03 kurtobando

It is because express-status-monitor sets up routing to the default path, /status.

const statusMonitor = require('express-status-monitor')();
app.use(statusMonitor);                           // sets up routing to default path: /status
app.get('/status', ..., statusMonitor.pageRoute); // req /status is handled earlier (never gets here)

You can set the default path to some other valid pathing, noting that it will be publicly accessible. In the following code, /secret is publicly accessible but /status is handled by your authentication middlewares.

const statusMonitor = require('express-status-monitor')({ path: '/secret' });
app.use(statusMonitor);                           // sets up routing to specified path: /secret
app.get('/status', ..., statusMonitor.pageRoute); // req /status is handled earlier (never gets here)

You can set the path to empty string (assuming the root path is handled earlier) to deny any routing.

const statusMonitor = require('express-status-monitor')({ path: '' });
app.use(statusMonitor);                           // req root is handled earlier (never get here)
app.get('/status', ..., statusMonitor.pageRoute); // req /status gets routed here

Or you can explicitly "reserve" a path and handle it by always sending 401.

app.get('/someReservedPath', (req, res) => { res.sendStatus(401); });
const statusMonitor = require('express-status-monitor')({ path: '/someReservedPath' });
app.use(statusMonitor);                           // req /someReservedPath is handled earlier (never gets here)
app.get('/status', ..., statusMonitor.pageRoute); // req /status gets routed here

lamweili avatar Jun 09 '22 15:06 lamweili