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

loofah

v0.0.7

Published

Scrubs sensitive information from data

Downloads

2,057

Readme

Loofah

A Javascript library that scrubs data.

Introduction

Scrubbers = require 'lib/loofah'

You often need to scrub sensitive information from data before moving it to an insecure location, or publishing it. For example, you may want to publish errors on Sentry and before doing this, you should ensure that you are not exposing fields like passwords, api keys or usernames. Loofah provides a number of easily extensible and configurable helper functions to remove these. For example, to redact all values associated with a key of password or secret you would call:

object = {a : {password: 'pwd', secrets: 'no match'}, secret: 'shhh'}
clean_object = Scrubbers.object_keys(['password', 'secret'])(object)
clean_object
// {a : {password: '[REDACTED]', secrets: 'no match'}, secret: '[REDACTED]'}

Library Functions

The loofah library provides a number of helper functions or scrubbers which operate on strings, objects and arrays. If given an object or array, the functions call themselves on all of its members using _.map or deepMapValues from underscore.deep. If the functions encounter something that is not a string, object or array it is returned unchanged.

Each helper function takes a list of keywords - in the example above these are password and secret. These return a function that can then be called on an object.

myscrubber = Scrubbers.object_keys(['password', 'secret'])
myscrubber({nothing: 'to scrub'})
// {nothing: 'to scrub'}
myscrubber({password: 'scrub this'})
// {password: '[REDACTED]'}

The keywords specify search terms and can either be regular expressions or strings. Some functions will scrub the match (substrings) while others expect the search term to be a key and will scrub the value that follows. Strings will be converted to regular expressions by the scrubber. The Regex will generally be case insensitive and need to match an entire key.

object_keys

If passed an object, redacts all information stored in a key that matches one of the keywords. If not passed an object, object_keys returns what it was given.

Scrubbers.object_keys(['secret', 'password'])({password: { a: 'pwd1', b: 'pwd2'}, secrets: 'not matched'})
// {password: { a: '[REDACTED]', b: '[REDACTED]'}, secrets: 'not matched'}

substrings

Redacts all substrings that match one of the keywords. If given an array or object substrings calls itself on each of the values. NB: Keywords passed as strings will be converted to case sensitive Regex

Scrubbers.substrings(['thisIsOurApiKey'])( "Don't steal our thisIsOurApiKey")
// Don't steal our [REDACTED]
Scrubbers.substrings(['thisIsOurApiKey'])(['wrong case thisisourapikey', 'look, thisIsOurApiKey'])
// ['wrong case thisisourapikey', 'look, [REDACTED]']

url_query_params

Redacts the value of a url encoded '<key>=<value>' pair where the key matches one of the keywords. If passed an array or object, url_query_params calls itself on each of the values.

Scrubbers.url_query_params(['client_id', 'client_secret'])('www.example.com/?CliENT_Id=123456789.apps.com&client_secret=123456789&grant_type=refresh_token')
// www.example.com/?CliENT_Id=[REDACTED].apps.com&client_secret=[REDACTED]&grant_type=refresh_token

key_value_pairs

Redacts the value of '<key><delim><value>' pairs in where the key matches one of the keywords. The delimiters can be specified in a string after the keywords, else they default to whitespace, = and :. If passed an array or object key_value_pairs calls itself on each of the values.

Scrubbers.key_value_pairs(['email', 'user'])("The user: NAME has email = [email protected]")
// The user: [REDACTED] has email = [REDACTED]
myscrubber = Scrubbers.key_value_pairs(['email', 'user'], "//s=:-") // delimiters are whitespace, '=', ':' and '-'
("The user: NAME has email - [email protected]")
// The user: [REDACTED] has email - [REDACTED]

Composition

_ = require 'underscore'

These functions can easily be composed using _.compose:

_.compose(Scrubbers.object_keys(['password', 'secret']), Scrubbers.substrings(['12345abcde']))(object)

Defaults

Loofah provides a default list of keywords for each of its functions (except substrings which should only be called with application specific values). You can call using the default configuration by providing no arguments.

Scrubbers.object_keys()(object)

You can also call all of the library functions (except substrings) with their defaults using:

Scrubbers.default()(object)
// equivalent to _.compose(key_value_pairs(), url_query_params(), object_keys())(object)

If the defaults are not quite right, you can add extra parameters by composition.

_.compose(Scrubbers.default(), Scrubbers.object_keys(['keys', 'not', 'in', 'defaults']))(object)

This will call object_keys twice; once with the parameters specified in defaults and once with your parameters. There is no way to remove parameters from the defaults other than editing the code.