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

snyk-policy

v4.1.2

Published

Snyk's policy parser and matching logic

Downloads

261,684

Readme

snyk-policy

Build Status Coverage Status

Loads Snyk policy files, typically name .snyk, parses them and returns a structure policy object.

From there, the policy object can filter vulnerabilities based on vuln.id and path (vuln.from) matching.

Policies can also load from multiple locations, and optionally support trusting deep policies, or ignoring all policies entirely.

How it works

The policy module is written to support future versions of policy formats, so you shouldn't need to worry about what version you're dealing with.

The policy is loaded, typically this will be a YAML file named .snyk (but can be loaded from another filename).

This returns an object that has the following public keys:

  • ignore Object
  • patch Object
  • suggest Object (optionally depending on the policy config)
  • version String

The ignore, patch and suggest all have similar top level structures. For example:

ignore: {
  '<snyk-vuln-id>': [
    {
      '<module path>': { <metadata> }
    }
  ]
}

The metadata for ignore and suggest are the same:

{
  reason: '<string>',
  expires: '<JSON date format>'
}

The metadata for patch is:

{
  patched: '<JSON date format>';
}

For a full example of a fully parsed policy file, see this fixture example.

The vulnerability report is passed in to the instance .filter function and the vulns are filtered out based on the ignore rules and the patch rules.

If there is any suggest keys on the policy a note property is added to the individual vulnerability it matches.

How filtering works

The filtering works on two levels:

  1. matches on vuln.id
  2. matches the vuln.from against the module path

If first (1) is satisfied, then (2) is checked. If ignoring, the vulnerability is stripped from the report.

If the rule is listed in the patches, the Snyk patch file is also checked to ensure it exists (this is a way to validate the patch has actually taken place - but note that this can be circumvented when the file system isn't available, see skipping patch verification.

A module path is constructed by the name and then optionally the version or version range. A star rule (*) is also supported.

Module path rules

Given the following dependency tree, and assuming we have a known vulnerability in [email protected]:

.
└─┬ @remy/[email protected]
  ├── [email protected]
  └─┬ [email protected]
    ├─┬ [email protected]
    │ └─┬ [email protected]
    │   └── [email protected]
    ├── [email protected]
    └─┬ [email protected]
      └─┬ [email protected]
        └── [email protected]

The following are examples of module paths that could target the semver vulnerability (note that the root module name is not part of the path, represented as . in the tree above):

@remy/protect-test > semver
@remy/[email protected] > [email protected]
* > semver
* > [email protected]

The first example rule (above) is how the policy is stored by default. However, policy files can be manually edited if desired.

Version ranges may also be used. For example, the following will all match the root dependency above:

@remy/[email protected]
@remy/protect-test@>=1.0.1
@remy/protect-test@^1.0.2

Usage

Installed via npm: npm install -S snyk-policy. Typically loaded and applied to vulnerabilities:

const policy = require('snyk-policy');

const vulns = snyk.test('[email protected]'); // assumes snyk is loaded
policy.load(process.cwd()).then((rules) => {
  console.log(rules.filter(vulns));
});

Skipping patch verification

Before the policy runs the filter, if the policy return object includes the property skipVerifyPatch: true then the check for the patch file will not be performed.

This is in use in the registry (private repo) and is useful when the policy loading doesn't have local access to the file system that the packages live on.

API

policy.load(root[, options])

Parses and loads a given directory or directories. Returns a promise.

root: String | Array

This can be a string pointing to a directory (if so, must include a .snyk file inside) or you can define the specific filename to load, i.e. ./my-policy.

If an array is given, the first policy is the primary, and the subsequent policies will inherit the module path from the primary policy.

Important: All secondary policy ignore rules are ignored and treated as suggestions, adding a note property on the vulnerability.

options: Object

  • ignore-policy: true ignores all the policy rules and returns an empty policy (use in snyk test --ignore-policy)
  • trust-policies: true applies ignore rules in secondary policies (and doesn't offer them as suggestions)
  • loose: true do not throw an exception if the policy can't be loaded from disk
  • `skipPatchValidation

policy.loadFromText(string)

Parses the string and returns the policy. Returns a promise.

string: String

A raw YAML string.

policy.save(config[, root, progress]) & .save([root, progress])

Save the policy to disk in the latest format, so if the original policy version was v1 and the newest is v2, the policy will be upgraded.

Note that this method is also available on the response object from .load, so can be called as res.save() (where res is the loaded config).

Returns a promise.

config: Object

The structure policy object.

root: String

The directory to save the policy file (.snyk). Defaults to CWD via process.cwd().

progress: Promise

A progress indicator, as used in snyk cli.

policy.filter(config, vulns) & .filter(vulns)

Applies the policy to the vulnerabilities object. The vulns object is expected as:

{
  ok: Boolean,
  vulnerabilities: Array
}

If all the vulns are stripped because of the policy, then the ok bool is set to true.

Note that this method is also available on the response object from .load, so can be called as res.filter() (where res is the loaded config).

Returns an object in the same structure as vulns.

policy.getByVuln(config, vuln)

Returns any matching rule given a specific vulnerability object. The vuln object must contain id and from to match correctly.

Returns an object structured as:

{
  type: String, // ignore | patch
  id: String, // vuln.id
  rule: Array, // array of package@version
  reason: String, // included in ignore rules
  expires: String, // JSON time included in ignore rules
}

config: Object

The loaded policy object (from .load).

vuln: Object

Single vulnerability object.

Sample policies

Note that <path to package> below is the dependency chain of package names and valid versions separated by a > symbol.

By default, the policy file does not add versions to these packages, so a path would look like: 'jade > transformers > uglify-js', but it can include versions. More details and examples can be seen in the module path rules section.

Ignore

ignore:
  '<snyk-vuln-id>':
    - '<path to package>':
        reason: String
        expires: String(format: Date().toJSON())
patch: {}
version: v1.0.0

Patch

patch:
  '<snyk-vuln-id>':
    - '<path to package>':
        patched: String(format: Date().toJSON())
version: v1

Misc