npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

secure-router

v3.1.2

Published

Helping you write more secure express apps.

Downloads

13

Readme

Secure Router

Build
Status

This node module implements a replacement for the Router that comes with Express. It provides a stricter security model, making your endpoints default to returning 401 Unauthorized or 403 Forbidden unless they have explicitly been authenticated and authorized.

This module helps you avoid situations where you set up a route but forget to add security middleware to it, leaving it unintentionally world-readable/writeable. Using it is easy:

import express from 'express';
import SecureRouter from 'secure-router';

const app = express();
const router = new SecureRouter();
router.bounceRequests();
app.use(router);

router.secureEndpoint({
  method: 'GET',
  path: '/the-crown-jewels',
  bouncers: [
    ((req) => if (req.user) return SecureRouter.AUTHENTICATE),
    ((req) => if (req.user.isRoyalty) return SecureRouter.AUTHORIZE),
  ],
  middleware (req, res) {
    req.send(theCrownJewels)
  },
});

/* OR */

secretRouter = router.secureSubpath({
  path: '/secrets',
  bouncers: [
    ((req) => if (req.user) return SecureRouter.AUTHENTICATE),
    ((req) => if (req.user.classification === 'MI6') return SecureRouter.AUTHORIZE),
    ((req) => if (req.user.number === '006') return return SecureRouter.DENY),
  ],
});

secretRouter.get('/mission-briefs', (req, res) => res.send(nextMission));

Bouncers

You can define an arbitrary number of bouncers on routes, paths, or entire routers.

Any bouncer can explicitly DENY, AUTHENTICATE, or AUTHORIZE a request for a path for which that bouncer has been defined. This can be done asynchronously, using a promise.

If any bouncer has elected to DENY, the request immediately short-circuits with a 401 status.

If no bouncer has elected to AUTHENTICATE, the request immediately short-circuits with a 401 status.

If no bouncer has elected to AUTHORIZE, the request immediately short-circuits with a 403 status.

Bouncer functions

All bouncers are individual functions, that accept a req and a res argument (this is the same req that an express middleware receives), and return a promise. If the promise resolves to anything other than SecureRouter.DENY, SecureRouter.AUTHENTICATE, SecureRouter.AUTHORIZE, or the result of SecureRouter.denyWith(), the bouncer is ignored.

Example:

const bouncer = function (req, res) {
  getSecurityClearanceLevel(req.user.id)
  .then(function (level) {
    if (level === 'TOP SECRET') return SecureRouter.AUTHORIZE;
    else return SecureRouter.denyWith({
      statusCode: 404,
      payload: 'Nothing to see here, move along.'
    });
  });
}

denyWith(<middleware|response>)

Returns a bouncer response that will cause the bouncer to deny the request, and will edit the response to whatever you specify. Takes either a function or a configuration object.

  • middleware: function(req, res, next), is parsed like any other express middleware.
  • response.statusCode: number, changes the statusCode of the response.
  • response.payload: one of the following:
    • string, is sent in the body of the response.
    • object, is sent in the body of the response.

Examples:

// with middleware
SecureRouter.denyWith(function (req, res, next) {
  // assuming AuthenticationError is defined elsewhere in your app
  // and handled later in another middleware that comes after bounceRequests
  return next(new AuthenticationError('Provide a site_token cookie!'));
}

// with a configuration object
SecureRouter.denyWith({
  statusCode: 404,
  payload: 'Nothing to see here, move along.'
});

Defining bouncers on individual endpoints

Use the secureEndpoint method:

router.secureEndpoint({
  method: 'GET',
  path: '/the-crown-jewels',
  bouncers: [bouncer1, bouncer2],
  middleware (req, res) {
    req.send(theCrownJewels);
  },
});
  • method: GET, POST, PUT, DELETE, etc...
  • path: appended to the path of the current router
  • bouncers: list of bouncers. Alternatively, use bouncer to pass only one bouncer
  • bouncer: individual bouncer. Alternatively, use bouncers to pass multiple bouncers
  • middleware: either an array of middleware or a function. Works the same way as normal express middleware.

Defining bouncers on subpaths

Use the secureSubpath method:

let subpathRouter = router.secureSubpath({
  path: '/secrets',
  bouncers: [bouncer1, bouncer2],
});

Returns a new instance of SecureRouter.

  • path: appended to the path of the current router
  • bouncers: list of bouncers. Alternatively, use bouncer to pass only one bouncer
  • bouncer: individual bouncer. Alternatively, use bouncers to pass multiple bouncers

Defining flat bouncers

These bouncers apply to all routes used by the current router. Use the bouncer method:

router.bouncer(bouncer);

Contributing

npm install
npm run test