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

@superpowerlabs/salus

v0.1.0-beta.1

Published

A set of security middleware to secure a webapp with rate limiting and CSP headers

Downloads

3

Readme

Salus

A set of security middlewares to secure a webapp with rate limiting and CSP headers

Installation

npm i @superpowerlabs/salus

Configuration

This package is designed to work with an express app that has a single index.html entrance for the website, and static routes for images, styles, etc.

You will need to provide the parameter that work for your web app in a salus.config.js file. You'll find a template at the root of the salus package https://github.com/superpowerlabs/salus/salus.config.js.template.

const config = {
  siteIndexFile: "../../build_latest/index.html",
  contentSecurityPolicy: {
    srcDefaults: ["'self'", "example.com"],
    skipCSP: ["styles", "images", "static"],
    directives: {
      defaultSrc: ["app.openlogin.com", "app.tor.us"],
      connectSrc: ["*.tor.us", "*.ankr.com", "*.walletconnect.org", "wss:"],
      fontSrc: ["fonts.gstatic.com/"],
      imgSrc: ["www.w3.org/"],
      scriptSrc: ["self", "use-nonce"],
      styleSrc: ["mysie.com/", "fonts.googleapis.com/", "app.tor.us/"],
    },
  },
  crossOriginEmbedderPolicy: {
    policy: "credentialless",
  },
  crossOriginOpenerPolicy: {
    policy: "same-origin-allow-popups",
  },
  crossOriginResourcePolicy: {
    policy: "cross-origin",
  },
  // options.allow is a boolean dictating whether to enable DNS prefetching. It defaults to false
  dnsPrefetchControl: {
    allow: true,
  },
  referrerPolicy: {
    policy: ["origin", "unsafe-url"],
  },
  expectCt: {
    maxAge: 86400,
    enforce: true,
    reportUri: "example.com",
  },
  hsts: {
    maxAge: 123456,
    includeSubDomains: false,
    preload: true,
  },
  //options.action is a string that specifies which directive to use—either DENY or SAMEORIGIN.
  frameguard: {
    action: "deny",
  },
  // options.permittedPolicies is a string that must be "none", "master-only", "by-content-type", or "all". It defaults to "none".
  permittedCrossDomainPolicies: {
    permittedPolicies: "master-only",
  },
  rateLimiter: {
    windowMs: 10000,
    max: 60,
  },
  debug: true,
};

module.exports = { config };

Setting the app to use salus

Here's an example on how to setup for an Express app:

require("dotenv").config();
const express = require("express");
const path = require("path");
// loading security related modules and configs
const { applyAll } = require("@superpowerlabs/salus");
const config = require("./salus.config");

const app = express();

// loading security and rate limiting
applyAll(app, config.config);

app.use(express.static(path.resolve(__dirname, "../public")));

module.exports = app;

Support nonce for JSS

Some javascript libraries like JSS inject content on the fly that triggers a CSP violation. Fortunately JSS provides a way to inject your nonce on the fly. Salus supports this JSS advanced behavior automaticaly if you insert the following meta tag in the head section of your Html:

<meta property="csp-nonce" />

Development

To run the tests (we recommend you install pnpm):

git clone https://github.com/superpowerlabs/salus
cd salus
pnpm i
pnpm test

Performance

In this section, we're using the app in the test folder to test the performance impact of running salus.

Setup

Start the app in test.

cd test
node index.js.hide

We're using Apache Bench (ab is included with MacOs, you'll have to install it on Windows and Linux).

Baseline: App without Salus

ab -n200 -c100 "http://localhost:3000/"
...cut
Total transferred:      109980 bytes
HTML transferred:       16570 bytes
Requests per second:    2353.13 [#/sec] (mean)
Time per request:       42.496 [ms] (mean)
Time per request:       0.425 [ms] (mean, across all concurrent requests)
Transfer rate:          1263.66 [Kbytes/sec] received
...cut

With Salus skipping assets

ab -n200 -c100 "http://localhost:3000/"
...cut
Total transferred:      90986 bytes
HTML transferred:       17387 bytes
Requests per second:    1862.35 [#/sec] (mean)
Time per request:       53.696 [ms] (mean)
Time per request:       0.537 [ms] (mean, across all concurrent requests)
Transfer rate:          827.38 [Kbytes/sec] received
...cut

With Salus not skipping assets

Telling salus to skip routes where static assets are served slightly improves performance. If we comment out the following line in salus.config.js we take all the asset routes through all the security middlewares and create a small performance hits.

ab -n200 -c100 "http://localhost:3000/"
...cut
Total transferred:      93580 bytes
HTML transferred:       16570 bytes
Requests per second:    1497.39 [#/sec] (mean)
Time per request:       66.783 [ms] (mean)
Time per request:       0.668 [ms] (mean, across all concurrent requests)
Transfer rate:          684.21 [Kbytes/sec] received
...cut

Read more

If you want to learn more about securing a web app:

  • https://content-security-policy.com/
  • https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

Contribute

Clone this repo. It uses PnPm. If you didn't have it globally, please install it:

npm i -g pnpm

Then

pnpm i
pnpm run prepare

History

0.1.0-beta.1

  • add support for JSS nonce through meta tag

0.1.0-beta.0

  • made Salus a class with 3 static methods: applyRateLimiter, applyCSP and applyAll
  • add config.noRateLimiter to explicitly skip the limiter

0.0.9-beta.5

  • fix issue with config.disableHelmet blocking all not-static assets from loading

To publish a new version

  • update history section of README
  • increment version: npm version 0.1.0-beta.1
  • test npm publish: npm publish --dry-run
  • check that everything looks ok in the output of the dryrun
  • publish the new version: npm publish

Credits

Author Yacin Bahi [email protected]

(c) 2022 Superpower Labs