Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

node-sec-patterns

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

node-sec-patterns - npm Package Compare versions

Comparing version 2.0.1 to 2.0.2

102

lib/mintable.js

@@ -20,3 +20,9 @@ 'use strict'

const { apply } = Reflect
const arrayMap = Array.prototype.map
const {
indexOf: arrayIndexOf,
join: arrayJoin,
map: arrayMap,
slice: arraySlice,
push: arrayPush
} = Array.prototype
const mapGet = Map.prototype.get

@@ -26,3 +32,3 @@ const mapSet = Map.prototype.set

const weakSetHas = WeakSet.prototype.has
const { lastIndexOf, substring } = String.prototype
const { lastIndexOf, split, substring } = String.prototype

@@ -57,2 +63,79 @@ const { dedot, dirname } = require('module-keys/lib/relpath.js')

/**
* Updates whitelist to add the target package to package whitelists
* for the given contract keys.
*/
function incorporateSelfNominationsFor (targetPackage, contractKeys) {
if (isArray(contractKeys)) {
for (let i = 0, nNoms = contractKeys.length; i < nNoms; ++i) {
if (apply(hasOwnProperty, contractKeys, [ i ])) {
const selfNomination = contractKeys[i]
whitelist[selfNomination] = whitelist[selfNomination] || []
apply(arrayPush, whitelist[selfNomination], [ targetPackage ])
}
}
}
}
function computeResolvePaths () {
const resolvePaths = []
const configRootParts = apply(split, configRoot, [ sep ])
for (let i = configRootParts.length; --i >= 0;) {
resolvePaths[resolvePaths.length] = `${
apply(
arrayJoin,
apply(arraySlice, configRootParts, [ 0, i + 1 ]),
[ sep ])
}${sep}node_modules`
}
return resolvePaths
}
/**
* Loads configuration files for packages whose self nominations have
* been seconded and modifies whitelist in place to incorporate them.
*/
function incorporateSelfNominations (second) {
const resolvePaths = computeResolvePaths()
for (let i = 0, nSeconds = second.length; i < nSeconds; ++i) {
if (apply(hasOwnProperty, second, [ i ])) {
let targetConfigPath = `${second[i]}`
if (!targetConfigPath) {
continue
}
// eslint-disable-next-line no-magic-numbers
if (apply(substring, targetConfigPath, [ targetConfigPath.length - 5 ]) !== '.json') {
targetConfigPath += '/package.json'
}
// Infer the target package name from the configuration path file
// "path/to/config.json" => "/abs/node_modules/path/to/config.json"
const resolvedTargetConfigPath = require.resolve(targetConfigPath, { paths: resolvePaths })
let targetPackage = resolvedTargetConfigPath
// "/abs/node_modules/path/to/config.json"
// => [ "", "abs", "node_modules", "path", "to", "config.json" ]
targetPackage = apply(split, targetPackage, [ '/' ])
// [ "", "abs", "node_modules", "path", "to", "config.json" ]
// => [ "path", "to", "config.json" ]
targetPackage = apply(
arraySlice, targetPackage,
[ apply(arrayIndexOf, targetPackage, [ 'node_modules' ]) + 1 ])
// [ "path", "to", "config.json" ] => [ "path" ]
// OR [ "@namespace", "path", "to", "..." ] => [ "@namespace", "path" ]
targetPackage = apply(
arraySlice, targetPackage,
[ 0, targetPackage[0][0] === '@' ? 2 : 1 ])
// [ "@namespace", "path" ] => "@namespace/path"
targetPackage = apply(arrayJoin, targetPackage, [ '/' ])
// Fetch the target configuration
// eslint-disable-next-line global-require
const targetConfig = require(resolvedTargetConfigPath)
incorporateSelfNominationsFor(
targetPackage,
((targetConfig && targetConfig.mintable) || {}).selfNominate)
}
}
}
/**
* Takes a configuration object with "mintableGrants" &| "mintableMode"

@@ -68,2 +151,3 @@ */

grants = {},
second,
mode

@@ -74,5 +158,7 @@ } = {}

whitelist = create(null)
try {
failureMode = modeFromConfig(options, mode)
// Defensively copy grants over
for (const key in grants) {

@@ -82,7 +168,15 @@ if (typeof key === 'string' && apply(hasOwnProperty, grants, [ key ])) {

if (isArray(val)) {
whitelist[key] = freeze(apply(arrayMap, val, [ (ele) => `${ele}` ]))
whitelist[key] = apply(arrayMap, val, [ (ele) => `${ele}` ])
}
}
}
if (isArray(second)) {
incorporateSelfNominations(second, whitelist)
}
} finally {
for (const key in whitelist) {
freeze(whitelist[key])
}
freeze(whitelist)

@@ -214,3 +308,3 @@ }

const { grants, pubKeys } = grantRecord
if (apply(weakSetHas, pubKeys, pubKey)) {
if (apply(weakSetHas, pubKeys, [ pubKey ])) {
// We've seen it before, great!

@@ -217,0 +311,0 @@ return true

2

package.json
{
"name": "node-sec-patterns",
"description": "Allow projects control over which dependencies can create objects that encapsulate security guarantees.",
"version": "2.0.1",
"version": "2.0.2",
"keywords": [

@@ -6,0 +6,0 @@ "design-patterns",

@@ -19,2 +19,3 @@ # Node security design patterns

* [Configuration](#configuration)
* [Suggesting grants](#suggesting-grants)
* [Defining a Mintable Type](#defining-a-mintable-type)

@@ -120,3 +121,90 @@ * [Example](#example)

### Suggesting grants
Library code may also suggest grants. It may **self nominate** for
certain privileges, and then an application may **second** those
privileges.
For example, if a library's package.json includes
```json
{
...
"mintable": {
"selfNominate": [
"contractKey0",
"contractKey1"
]
}
}
```
and an application's package.json includes
```json
{
...
"mintable": {
"second": [
"path/to/library"
]
}
}
```
then `Mintable.minterFor` will behave as if the application's
package.json had done
```json
{
...
"mintable": {
"grants": {
"contractKey0": [ "path/to/library" ],
"contractKey1": [ "path/to/library" ]
}
}
}
```
Application maintainers can run the below to see what effect self nominations have,
but keep in mind that a package might change its self nominations in future versions so
seconding self-nominated grants for a module is placing trust in that module's future
development practices.
```sh
$ node -e 'for (const second of require(`./package.json`).mintable.second) {
const config = /[.]json$/.test(second) ? second : `${ second }/package.json`;
console.group(second);
console.log(JSON.stringify(require(config).mintable.selfNominate, null, 2));
console.groupEnd();
}'
```
Seconded nominations are resolved using the following algorithm:
1. for (targetConfigPath of configuration.mintable.second)
1. Make sure we're loading a configuration file:
1. if targetConfigPath does not end with `.json` then targetConfigPath += '/package.json'
1. Infer the target package name from the configuration path file:
1. let targetPackage = require.resolve(targetConfigPath)
1. targetPackage = targetPackage.split('/')
1. targetPackage = targetPackage.slice(targetPackage.indexOf('node_modules') + 1)
1. targetPackage = targetPackage.slice(0, targetPackage[0][0] === '@' ? 2 : 1)
1. targetPackage = targetPackage.join('/')
1. Fetch the target configuration
1. let targetConfig = require(targetConfigPath)
1. Incorporate any self nominations into the application's grants
1. let selfNominations = (targetConfig.mintable || {}).selfNominate || []
1. for (selfNomination of selfNominations)
1. grants[selfNomination] = grants[selfNomination] || []
1. grants[selfNomination].push(
If a self nomination path ends in `.json` then `/package.json` is not appended to the
config file.
Internal package directories are stripped when figuring out to whom access is granted.
## Defining a Mintable Type

@@ -123,0 +211,0 @@ Mintable types are subclasses of `class Mintable` exported by this module.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc