Giter Club home page Giter Club logo

audit-ci's Introduction

audit-ci

npm version CircleCI GitHub CI CodeQL

This module is intended to be consumed by your favourite continuous integration tool to halt execution if npm audit, yarn audit or pnpm audit finds vulnerabilities at or above the specified threshold while ignoring allowlisted advisories.

Note: Use our codemod to update to audit-ci v6.0.0

Requirements

  • Node >=16
  • (Optional) Yarn ^1.12.3 || Yarn >=2.4.0
  • (Optional) PNPM >=4.3.0

Limitations

  • Yarn Classic workspaces does not audit devDependencies. See this issue for more information.

Set up

(Recommended) Install audit-ci during your CI environment using npx, yarn dlx, or pnpm dlx immediately after checking out the project's repository.

# Use the option for your project's package manager, pinning to a major version to avoid breaking changes
npx audit-ci@^7 --config ./audit-ci.jsonc
yarn dlx audit-ci@^7 --config ./audit-ci.jsonc
pnpm dlx audit-ci@^7 --config ./audit-ci.jsonc

Alternatively, audit-ci can be installed as a devDependency. The downside of this approach is that the CI may run a postinstall script of a compromised package before running audit-ci.

# Use the option for your project's package manager
npm install -D audit-ci
yarn add -D audit-ci
pnpm install -D audit-ci

The next section gives examples using audit-ci in various CI environments. It assumes that moderate, high, and critical severity vulnerabilities prevent build continuation. Also, it suppresses an advisory of axios and a transitive advisory of react-scripts.

// audit-ci.jsonc
{
  // $schema provides code completion hints to IDEs.
  "$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
  "moderate": true,
  "allowlist": [
    // Axios denial of service https://github.com/advisories/GHSA-42xw-2xvc-qx8m
    "GHSA-42xw-2xvc-qx8m",
    // The following are for the latest create-react-app
    // https://github.com/advisories/GHSA-rp65-9cf3-cjxr
    // Alternatively, allowlist "GHSA-rp65-9cf3-cjxr" to suppress this nth-check advisory across all paths
    // or "*|react-scripts>*" to suppress advisories for all transitive dependencies of "react-scripts".
    "GHSA-rp65-9cf3-cjxr|react-scripts>@svgr/webpack>@svgr/plugin-svgo>svgo>css-select>nth-check"
  ]
}

Allowlisting

Allowlists are a mechanism to suppress an advisory warning from the audit. A team may want to suppress an advisory when:

  • A fix has already been started
  • There is no bandwidth to fix the advisory
  • The risk is tolerable for the project
  • The advisory is inaccurate or incorrect
  • The vulnerable code is not actually used

An allowlist may contain multiple allowlist records. There are three categories of allowlist record formats:

  • module allowlist record (example: axios, suppresses all advisories directly caused by axios, not transitive advisories)
  • advisory allowlist record (example: GHSA-42xw-2xvc-qx8m, suppresses all instances of advisory based on the GitHub advisory identifier)
  • path allowlist record (example: GHSA-rp65-9cf3-cjxr|react-scripts>@svgr/webpack>@svgr/plugin-svgo>svgo>css-select>nth-check, the specific and full advisory path with wildcard support)

When audit-ci identifies new advisories at or above the configured level, the CI pipeline will fail.

Found vulnerable advisory paths:
GHSA-pw2r-vq6v-hr8c|axios>follow-redirects
GHSA-74fj-2j2h-c42q|axios>follow-redirects
GHSA-4w2v-q235-vp99|axios
GHSA-42xw-2xvc-qx8m|axios
GHSA-cph5-m8f7-6c5x|axios
Failed security audit due to high, moderate vulnerabilities.
Vulnerable advisories are:
https://github.com/advisories/GHSA-pw2r-vq6v-hr8c
https://github.com/advisories/GHSA-74fj-2j2h-c42q
https://github.com/advisories/GHSA-4w2v-q235-vp99
https://github.com/advisories/GHSA-42xw-2xvc-qx8m
https://github.com/advisories/GHSA-cph5-m8f7-6c5x
Exiting...

Advisories can be suppressed using several approaches. Each approach is useful in unique scenarios.

First, the most granular and secure approach, using paths. If in the future the same advisory arises with a different path, the pipeline will fail.

"allowlist": [
  "GHSA-pw2r-vq6v-hr8c|axios>follow-redirects",
  "GHSA-74fj-2j2h-c42q|axios>follow-redirects",
  "GHSA-4w2v-q235-vp99|axios",
  "GHSA-42xw-2xvc-qx8m|axios",
  "GHSA-cph5-m8f7-6c5x|axios"
]

The next best approach is suppressing the advisories using advisory IDs. This approach may be useful if your team knows that the application is not (and will not be) affected by the advisory regardless of the path. Often, the same advisory can be present in many paths. Allowlisting by advisory ID is terser than the alternative of listing all paths.

"allowlist": [
  "GHSA-pw2r-vq6v-hr8c",
  "GHSA-74fj-2j2h-c42q",
  "GHSA-4w2v-q235-vp99",
  "GHSA-42xw-2xvc-qx8m",
  "GHSA-cph5-m8f7-6c5x"
]

The next approach is to allowlist the modules themselves. All current and future advisories are automatically suppressed when using module allowlist records. Compared to other suppression approaches, there's an increased risk of a new advisory impacting your application due to the broad suppression. Suppressing via a module allowlist record is often less useful than using path allowlist records + wildcards, as noted in the final approach.

"allowlist": [
  "axios",
  "follow-redirects"
]

Finally, wildcards can be used within path allowlist records. Wildcards are useful for trusted development-only dependencies such as react-scripts. Unlike the module allowlist record of react-scripts, the path allowlist of *|react-scripts>* suppresses transitive dependency advisories (dependencies of dependencies).

Wildcard matching works by:

  1. splitting the allowlist record at every wildcard
  2. constructing a regex matching anything at each wildcard location

An allowlist record may include any number of wildcards such as *|react-scripts>*>*>example>*.

Allowlist Formats

The simplest way to add an advisory to the allowlist is using a string:

"allowlist": [
  "axios"
]

You can also use an object notation (NSPRecord) in which you can add notes and control the expiration of this exception:

"allowlist": [
  {
    "axios": {
      "active": true,
      "notes": "Ignore this until November 20th",
      "expiry": "20 November 2022 11:00"
    }
  }
]

allowlist supports both formats at the same time, so feel free to mix and match:

"allowlist": [
  {
    "axios": {
      "active": true,
      "notes": "Ignore this until November 20th",
      "expiry": "20 November 2022 11:00"
    }
  },
  "base64url"
]

NSPRecord Fields

Attribute Type Description Example
active boolean Whether the exception is active or not true
expiry string | number Human-readable date, or milliseconds since the UNIX Epoch - '2020-01-31'
- '2020/01/31'
- '01/31/2021, 11:03:58'
- '1 March 2016 15:00'
- '1 March 2016 3:00 pm'
- '2012-01-26T13:51:50.417-07:00'
- 'Sun, 11 Jul 2021 03:03:13 GMT'
- 'Thu Jan 26 2017 11:00:00 GMT+1100 (Australian Eastern Daylight Time)'
- 327611110417
notes string Notes related to the vulnerability.

GitHub Actions

steps:
  - uses: actions/checkout@v2
  - name: Audit for vulnerabilities
    run: npx audit-ci@^7 --config ./audit-ci.jsonc

(Recommended) Run audit-ci immediately after checking out the git repository to reduce the risk of executing a postinstall script from a compromised NPM package.

CircleCI

# ... excludes set up for job
steps:
  - checkout
  - run:
      name: update-npm
      command: "sudo npm install -g npm"
  - restore_cache:
      key: dependency-cache-{{ checksum "package.json" }}
  # This should run immediately after cloning
  # the risk of executing a script from a compromised NPM package.
  # If you use a pull-request-only workflow,
  # it's better to not run audit-ci on `main` and only run it on pull requests.
  # For more info: https://github.com/IBM/audit-ci/issues/69
  # For a PR-only workflow, use the below command instead of the above command:
  #
  # command: if [[ ! -z $CIRCLE_PULL_REQUEST ]] ; then npx audit-ci --config ./audit-ci.jsonc ; fi
  - run:
      name: run-audit-ci
      command: npx audit-ci@^7 --config ./audit-ci.jsonc
  - run:
      name: install-npm
      command: "npm install --no-audit"

Travis-CI

Auditing only on PR builds is recommended

scripts:
  # This script should be the first that runs to reduce the risk of
  # executing a script from a compromised NPM package.
  - if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then npx audit-ci@^7 --config ./audit-ci.jsonc; fi

For Travis-CI not using PR builds:

scripts:
  - npx audit-ci@^7 --config ./audit-ci.jsonc

Options

(Recommended) Prefer to use a JSONC or JSON5 config file for audit-ci over managing your config with CLI arguments. Using a config file supports workflows such as documenting your allowlist, centralized and easier config management, and code completion when using the $schema field.

Args Alias Description
-l --low Prevents integration with low or higher vulnerabilities (default false)
-m --moderate Prevents integration with moderate or higher vulnerabilities (default false)
-h --high Prevents integration with high or critical vulnerabilities (default false)
-c --critical Prevents integration only with critical vulnerabilities (default false)
-p --package-manager Choose a package manager [choices: auto, npm, yarn, pnpm] (default auto)
-a --allowlist Vulnerable modules, advisories, and paths to allowlist from preventing integration (default none)
-o --output-format The format of the output of audit-ci [choices: text, json] (default text)
-d --directory The directory containing the package.json to audit (default ./)
--pass-enoaudit Pass if no audit is performed due to the registry returning ENOAUDIT (default false)
--show-found Show allowlisted advisories that are found (default true)
--show-not-found Show allowlisted advisories that are not found (default true)
--registry The registry to resolve packages by name and version for auditing (default to unspecified)
--report-type Format for the audit report results [choices: important, summary, full] (default important)
--retry-count The number of attempts audit-ci calls an unavailable registry before failing (default 5)
--config Path to the audit-ci configuration file
--skip-dev Skip auditing devDependencies (default false)
--extra-args Extra arguments to pass to the underlying audit command (default: [])

Config file specification

A config file can manage auditing preferences for audit-ci. The config file's keys match the CLI arguments.

{
  "$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
  // Only use one of ["low": true, "moderate": true, "high": true, "critical": true]
  "low": <boolean>, // [Optional] defaults `false`
  "moderate": <boolean>, // [Optional] defaults `false`
  "high": <boolean>, // [Optional] defaults `false`
  "critical": <boolean>, // [Optional] defaults `false`
  "allowlist": <(string | [NSPRecord](#nsprecord-fields))[]>, // [Optional] default `[]`
  "report-type": <string>, // [Optional] defaults `important`
  "package-manager": <string>, // [Optional] defaults `"auto"`
  "output-format": <string>, // [Optional] defaults `"text"`
  "pass-enoaudit": <boolean>, // [Optional] defaults `false`
  "show-found": <boolean>, // [Optional] defaults `true`
  "show-not-found": <boolean>, // [Optional] defaults `true`
  "registry": <string>, // [Optional] defaults `undefined`
  "retry-count": <number>, // [Optional] defaults 5
  "skip-dev": <boolean>, // [Optional] defaults `false`
  "extra-args": <string>[] // [Optional] defaults `[]`
}

Refrain from using "directory" within the config file because directory is relative to where the command is run, rather than the directory where the config file exists.

Examples

Prevents build on moderate, high, or critical vulnerabilities with allowlist; ignores low

With a JSONC config file, execute with npx audit-ci --config ./audit-ci.jsonc.

// audit-ci.jsonc
{
  // $schema provides code completion hints to IDEs.
  "$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
  "moderate": true,
  "allowlist": [
    // Axios denial of service https://github.com/advisories/GHSA-42xw-2xvc-qx8m
    "GHSA-42xw-2xvc-qx8m",
    // The following are for the latest create-react-app
    // https://github.com/advisories/GHSA-rp65-9cf3-cjxr
    // Alternatively, allowlist "GHSA-rp65-9cf3-cjxr" to suppress this nth-check advisory across all paths
    // or "*|react-scripts>*" to suppress advisories for all transitive dependencies of "react-scripts".
    "GHSA-rp65-9cf3-cjxr|react-scripts>@svgr/webpack>@svgr/plugin-svgo>svgo>css-select>nth-check"
  ]
}

Or, with the CLI:

npx audit-ci -m -a "GHSA-42xw-2xvc-qx8m" "GHSA-rp65-9cf3-cjxr|react-scripts>@svgr/webpack>@svgr/plugin-svgo>svgo>css-select>nth-check"

Prevents build on any vulnerability except advisory "GHSA-38f5-ghc2-fcmv" and all of lodash and base64url, don't show allowlisted

With a JSON5 config file:

// JSON5 files support trailing commas and more succinct syntax than JSONC files.
{
  $schema: "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
  low: true,
  allowlist: ["GHSA-38f5-ghc2-fcmv", "lodash", "base64url"],
  "show-found": false,
}

Or, with the CLI with yarn dlx:

yarn dlx audit-ci@^7 -l -a "GHSA-38f5-ghc2-fcmv" lodash base64url --show-found false

Prevents build with critical vulnerabilities showing the full report

With a JSONC config file:

{
  "$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
  "critical": true,
  "report-type": "full"
}

Or, with the CLI with pnpm dlx:

pnpm dlx audit-ci@^7 --critical --report-type full

Continues build regardless of vulnerabilities, but show the summary report

With a JSONC config file:

{
  "$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
  "report-type": "summary"
}

Or, with the CLI:

npx audit-ci@^7 --report-type summary

Pass additional args to Yarn Berry to exclude a certain package from audit

With a JSONC config file, in a project on Yarn Berry v3.3.0 or later:

{
  "$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
  "extra-args": ["--exclude", "example"]
}

Or, with the CLI:

npx audit-ci@^7 --extra-args '\--exclude' example

Example config file and different directory usage

test/npm-config-file/audit-ci.jsonc

{
  "$schema": "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
  "low": true,
  "package-manager": "auto",
  "allowlist": [
    "GHSA-333w-rxj3-f55r",
    "GHSA-vfvf-mqq8-rwqc",
    "example1",
    "example2",
    "GHSA-6354-6mhv-mvv5|example3",
    "GHSA-42xw-2xvc-qx8m|example4",
    "GHSA-42xw-2xvc-qx8m|example5>example4",
    "*|example6>*"
  ],
  "registry": "https://registry.npmjs.org"
}
npx audit-ci@^7 --directory test/npm-config-file --config test/npm-config-file/audit-ci.jsonc

test/pnpm-config-file/audit-ci.json5

{
  $schema: "https://github.com/IBM/audit-ci/raw/main/docs/schema.json",
  moderate: true,
  "package-manager": "pnpm",
  allowlist: [
    "GHSA-vfvf-mqq8-rwqc",
    "example2",
    "GHSA-6354-6mhv-mvv5|example3",
    "GHSA-42xw-2xvc-qx8m|example5>example4",
    "*|example6>*",
  ],
}
npx audit-ci@^7 --directory test/pnpm-config-file --config test/pnpm-config-file/audit-ci.json5

Codemod

npx @quinnturner/audit-ci-codemod

https://github.com/quinnturner/audit-ci-codemod

audit-ci v6.0.0 changed the identifiers used for auditing from the NPM identifiers to GitHub identifiers. NPM identifiers are considered unstable to rely on, as they frequently change. Meanwhile, GitHub identifiers are stable. To accommodate for a potentially tedious migration, a codemod is available to update your configuration in-place.

$ npx @quinnturner/audit-ci-codemod
Need to install the following packages:
  @quinnturner/audit-ci-codemod
Ok to proceed? (y) y
? What's the path for the audit-ci config? audit-ci.jsonc
Performed migration from advisories, whitelist, and path-whitelist to allowlist
Performed migration from NPM advisories to GitHub advisories

Q&A

Why run audit-ci on PR builds for Travis-CI and not the push builds?

If audit-ci is run on the PR build and not on the push build, you can continue to push new code and create PRs parallel to the actual vulnerability fix. However, they can't be merged until the fix is implemented. Since audit-ci performs the audit on the PR build, it will always have the most up-to-date dependencies vs. the push build, which would require a manual merge with main before passing the audit.

What do I do when NPM/Yarn is breaking my build while returning ENOAUDIT?

The config option --pass-enoaudit allows passing if no audit is performed due to the registry returning ENOAUDIT. It is false by default to reduce the risk of merging in a vulnerable package. However, if the convenience of passing is more important for your project then you can add --pass-enoaudit into the CLI or add it to the config.

audit-ci's People

Contributors

alexhladin avatar arokor avatar capaj avatar clement-escolano avatar davewasmer avatar dependabot[bot] avatar diogovcs avatar djomaa avatar dw2 avatar g-rath avatar imaman avatar iranreyes avatar jdanil avatar kyletsang avatar mobilutz avatar oleksiydubovyk avatar p-v-d-veeken avatar quinnturner avatar sanniassin avatar sargunv avatar sumanapotturu avatar whatifwedigdeeper avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

audit-ci's Issues

Runs forever, CPU at 145%, when using nodejs v8.15.0

Yeah, that title says it all. Just

  • run yarn run audit-ci <whatever> using nodejs v8.15.0,
  • have a coffee and
  • come back
  • Still running and CPU is blocking my system.

Changed to nodejs v10 and 12, works fine there. Happens with audit-ci v1.5.0 and latest v2.3.0 both.

Would be nice to have a verbose mode so that I can see where exactly your audit tool is stuck with.

Cannot JSON.parse response - goes over Node heap size

Two recent high level advisories - mixin-deep and set-value blocked my CI even though I am running audit-ci --critical. The issue being that it fail on memory while trying to parse a huge JSON output containing each and every path where these two are dependencies, basically reaching a default Node heap size of ~1.4M.

Output starting with:

οΏ½[32;1m$ yarn run auditοΏ½[0;m
yarn run v1.13.0
$ audit-ci --critical
οΏ½[36mYarn audit report summary:οΏ½[0m
οΏ½[31mERROR: Cannot JSON.parse response:οΏ½[0m
{"type":"auditAdvisory","data":{"resolution":{"id":1012,"path":"jest>jest-cli>@jest/core>@jest/reporters>@jest/environment>@jest/transform>jest-haste-map>jest-util>@jest/fake-timers>jest-message-util>micromatch>extglob>snapdragon>base>cache-base>set-value","dev":false,"optional":false,"bundled":false},"advisory":{"findings":[{"version":"2.0.0","paths":["awesome-typescript-loader>micromatch>braces>snapdragon>base>cache-base>set-value","awesome-typescript-loader>micromatch>extglob>expand-brackets>snapdragon>base>cache-base>set-value","awesome-typescript-loader>micromatch>
...

...and ending with:

οΏ½[31mERROR: Cannot JSON.parse response:οΏ½[0m
<--- Last few GCs --->
οΏ½[31mERROR: Cannot JSON.parse response:οΏ½[0m
[19713:0x40f5e30]    10373 ms: Mark-sweep 1396.4 (1439.9) -> 1396.4 (1439.9) MB, 100.2 / 0.0 ms  (+ 27.5 ms in 2 steps since start of marking, biggest step 21.4 ms, walltime since start of marking 128 ms) (average mu = 0.116, current mu = 0.003) allocatio[19713:0x40f5e30]    10498 ms: Mark-sweep 1396.4 (1439.9) -> 1396.4 (1439.9) MB, 125.5 / 0.0 ms  (average mu = 0.065, current mu = 0.001) allocation failure scavenge might not succeed
οΏ½[31mUnexpected end of JSON inputοΏ½[0m
οΏ½[31mExiting...οΏ½[0m
οΏ½[31mERROR: Cannot JSON.parse response:οΏ½[0m
<--- JS stacktrace --->
οΏ½[31mERROR: Cannot JSON.parse response:οΏ½[0m
Cannot get stack trace in GC.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
οΏ½[31;1mERROR: Job failed: exit status 1
οΏ½[0;m

Audit randomly fails due to 503 (Yarn and NPM)

Hello,

I am using audit-ci in my CircleCI workflow (thank you for this package). I have a annoying issue: sometimes, the audit fails with the error:

Invocation of npm audit failed:
npm ERR! code ENOAUDIT
npm ERR! audit Your configured registry (https://registry.npmjs.org/) does not support audit requests.
npm ERR! A complete log of this run can be found in:
npm ERR!     /home/circleci/.npm/_logs/2019-04-03T14_57_17_893Z-debug.log
Exiting...

I understand this seems to be an error from NPM server and not audit-ci itself, however, I never encountered this error while running npm audit locally on the project.

This error is very random: sometimes it occurs 5 times in a row, sometimes it does not happen for days.

Did some of you stumble upon this issue? Do you know if we can implement some kind of retying mechanism in audit-ci to circumvent it?

Thank you

[Documentation/CircleCI]: Only build on the merge, not PR

In Travis-CI, we only build on the merge, not the PR.

script:
  # Have audit-ci run audit-ci to audit itself :)
  - if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then node lib/audit-ci.js -l --config ./audit-ci.json; fi

However, on CircleCI, we build on the PR:

      # In your code, add this (after installing with `npm install --save-dev audit-ci`):
      # - run:
      #    name: run-audit-ci
      #    command: 'audit-ci --moderate'

      # Have audit-ci run audit-ci to audit itself :)
      - run:
          name: run-audit-ci
          command: node lib/audit-ci.js -l --config ./audit-ci.json

This can result in the following scenario:

  1. Push a new feature with PR, but master has new vulnerabilities, breaking the PR
  2. Create a fix PR with the new advisories, merge PR into master
  3. Re-run the feature workflow
    • Travis-CI will pass
    • CircleCI will fail

The expected behaviour (Travis-CI and CircleCI): pass.
The current behaviour: Travis-CI - pass, CircleCI - fail.

image

CircleCI should build on the merge rather than the PR.

This issue would be resolved by:

  1. Updating the docs to suggest the new CircleCI workflow implementation
  2. Implement the new CircleCI workflow

Only return exit code 1 when known vulnerability is detected

With the NPM audit service having intermittent issues for a week, I think audit-ci should only exit with 1 if a vulnerability is present. It currently exists with 1 due to the NOAUDIT error received from the NPM registry.

Screen Shot 2019-05-21 at 4 29 09 PM

Right now my CI builds are failing intermittently and I have to manually disable runs of audit-ci on all my repos. I'd prefer the behavior that environmental issues are ignored and only verified vulnerabilities cause a pipeline error.

Perhaps make this configurable?

Introduce tests into CircleCI and Travis-CI

The test folder contains package.jsons that have each level of vulnerability severity.

This issue focuses on integrating npm install && node ../index.js -{test cases} into the CI environments.

[Feature]: Fail on whitelisted advisories that are not found

Hi, thanks for this great tool, here's an idea I've been thinking about:

The process for managing CVEs is typically to attempt to patch the affected libraries and if no patch is available, verify the risk of the CVE and if it is low, whitelist the CVE.

At some point the issue is fixed in an dependency, and the CVE no longer needs to be whitelisted and audit-ci helpfully gives a message about this, but since a CI build somewhere does not fail, this message is generally ignored.

This potentially becomes an issue in cases where the CVE reappears in the future, maybe in a different library, or maybe in the same one, but after the use of that library has materially changed. In these cases the CVE should be reassessed, but because the whitelist lingered in the config if is missed.

If there were a flag to give an error code .e.g. --fail-not-found then the above would be mitigated and it would also catch copy/paste mistakes where excessive advisories are whitelisted across multiple repos.

Any thoughts?

Dave

Introduce a path argument

Suggested specification

  • Optional, with the default being the current directory
  • arg: -d, alias: --directory
  • Must support relative paths: --directory ../../path/to/project, or -d ../../path/to/project/
  • Should support absolute paths (though I am unsure of the consequences within various CIs): --path /home/<PATH>/
  • If an NPM package is not found at that path, it should exit with and error code

Introducing a relative path could potentially be useful for lerna projects, where the CI will perform multiple audits. It could also be useful for introducing audit-ci into scripts, where the script can reside anywhere.

Option to only output a summary report

First of all, thank for the effort, I was playing with my own npm package for the CI-friendly yarn audit wrapper before I've found this one, which is very nice and mature.

What I am currently missing is an option to only include a summary report (JSON or not).

I've faced the following when running audit-ci -c (only fail on criticals). On the one hand having no report at all seems insufficient (we might have hundreds on major issues, but see nothing, just the successful pass):

$ audit-ci -c --report false
Passed yarn security audit.

On the other hand in the same situation the output JSON is too huge, particularly going way over the GitLab CI job log limitation:

$ audit-ci -c
Yarn audit report JSON-lines:
{
  "type": "auditAdvisory",
  "data": {
    "resolution": {
      "id": 786,
      "path": "ts-jest>cpx>chokidar>anymatch>micromatch>braces",
      "dev": false,
      "optional": false,
      "bundled": false
    },

    ... SO MANY LINES ...

      "jest>jest-cli>jest-runner>jest-config>babel-jest>babel-plugin-istanbul>istanbul-lib-instrument>babel-template>babel-traverse>lodash",
      "jest>jest-cli>jest-runner>jest-config>babel-jest>babel-plugin-istanbul>istanbul-lib-instrument>babel-template>babel-types>lodash",
      "jest>jest-cli>jest-runner>jest-con
Job's log exceeded limit of 4194304 bytes.

Having a summary JSON only like the part below would be optimal in this case:

{
  "type": "auditSummary",
  "data": {
    "vulnerabilities": {
      "info": 0,
      "low": 9,
      "moderate": 213,
      "high": 4,
      "critical": 0
    },
    "dependencies": 70026,
    "devDependencies": 0,
    "optionalDependencies": 0,
    "totalDependencies": 70026
  }
}
Passed yarn security audit.

We could either extend --report to support full, summary, none (as opposed to current boolean).
Or add another option like --summary, -s.

npm show causing EAUTHUNKNOWN with VSO Package feeds

Hey, I realise that this is likely a limitation / bug within VSO's package feed itself and have raised it as an issue over there.

The recent addition of "npm show audit-ci version" in 2.4.2 is causing an authentication issue in Azure DevOps, even with an authenticated token in my projects .npmrc (No issues with npm installs etc, so authentication is working fine).

I don't think there is any way to avoid this other than fixing my version to 2.4.1, or am I missing something here?

Not correctly handling non-JSON yarn error

audit-ci is failing with the following error:

$ audit-ci --moderate --report false
undefined:1
/opt/yarn-v1.12.3/lib/cli.js:65876
^

SyntaxError: Unexpected token / in JSON at position 0
    at JSON.parse (<anonymous>)
    at Socket.proc.stderr.on.jsonl (/a/workspace/Watson-Discovery_cnc-ui_develop/node_modules/audit-ci/lib/yarn-auditer.js:76:30)
    at Socket.emit (events.js:182:13)
    at addChunk (_stream_readable.js:283:12)
    at readableAddChunk (_stream_readable.js:260:13)
    at Socket.Readable.push (_stream_readable.js:219:10)
    at Pipe.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
error Command failed with exit code 1.

It appears that yarn is failing, but audit-ci is trying to parse the output text as JSON, which it is not.

const errorLine = JSON.parse(jsonl);

[Discussion]: Drop support for Node 6

Node 6 has been end-of-life since Apr 30th, 2019. Node 8 has been end-of-life since Dec 31st, 2019, but is still in maintenance period.

Dependent packages that have dropped support for Node 6 that have prevented us upgrading:

Feel free to discuss what your thoughts are on this!

[Feature] Package names in summary audit report

Hi, I think it would be useful to include a summary of affected packages in the audit report much like how yarn audit displays it. My issue is the audit summary displays too little information, but the full report displays too much. Thank you for considering, and more than happy to put in a PR if needed.

Not all of the output is captured causing JSON parse errors

I always get this error when running against a few of my projects with similar dependencies. It seems to be caused by buffers not being flushed so not all the output is captured, or buffer size not big enough, or something like that.

Had some trouble attaching files. Logs at https://gist.github.com/callum-p/5efc1226f35ff6dacba53d950ca21f43

user@l0calhost:~/repos/xx/xx-xx-xx-xx(develop)$ docker run --rm -v $PWD:/analyse node:10.8.0-alpine /bin/sh -c "npm install -g audit-ci && cd /analyse && audit-ci"
/usr/local/bin/audit-ci -> /usr/local/lib/node_modules/audit-ci/bin/audit-ci
+ [email protected]
added 56 packages from 12 contributors in 2.258s
Invalid output
Exiting...

[Discussion]: Remove package-lock.json

To reduce the number of packages for clients to download, we can remove the package-lock.json.

This does have security implications under-the-hood since the entire dependency tree is managed through package-lock.json for more consistent installations.

Carriage return in bin/audit-ci

I'd open a PR for this, but doesn't appear that the master branch has this issue.

With v1.0.1 on a non-Windows machine, this is the output error: /usr/bin/env: β€˜node\r’: No such file or directory

Revealed via: cat -A node_modules/audit-ci/bin/audit-ci; output:

#!/usr/bin/env node^M$
require('../');

[Security] Advisory 788

Info

Breaking build https://travis-ci.com/IBM/audit-ci/builds/106382588

Advisory: https://npmjs.com/advisories/788

Audit result

{
  "actions": [
    {
      "action": "update",
      "module": "js-yaml",
      "depth": 3,
      "target": "3.13.0",
      "resolves": [
        {
          "id": 788,
          "path": "eslint>js-yaml",
          "dev": true,
          "optional": false,
          "bundled": false
        },
        {
          "id": 788,
          "path": "husky>cosmiconfig>js-yaml",
          "dev": true,
          "optional": false,
          "bundled": false
        }
      ]
    },
    {
      "action": "review",
      "module": "js-yaml",
      "resolves": [
        {
          "id": 788,
          "path": "mocha>js-yaml",
          "dev": true,
          "optional": false,
          "bundled": false
        }
      ]
    }
  ],
  "advisories": {
    "788": {
      "findings": [
        {
          "version": "3.12.0",
          "paths": [
            "eslint>js-yaml",
            "husky>cosmiconfig>js-yaml",
            "mocha>js-yaml"
          ],
          "dev": true,
          "optional": false,
          "bundled": false
        }
      ],
      "id": 788,
      "created": "2019-03-18T21:29:08.514Z",
      "updated": "2019-03-21T20:31:05.113Z",
      "deleted": null,
      "title": "Denial of Service",
      "found_by": {
        "link": "https://sites.google.com/site/jensdietrich/",
        "name": "Shawn Rasheed, Jens DIetrich"
      },
      "reported_by": {
        "link": "https://conf.researchr.org/profile/shawnrasheed",
        "name": "Shawn Rasheed"
      },
      "module_name": "js-yaml",
      "cves": [],
      "vulnerable_versions": "<3.13.0",
      "patched_versions": ">=3.13.0",
      "overview": "Versions `js-yaml` prior to 3.13.0 are vulnerable to Denial of Service. By parsing a carefully-crafted YAML file, the node process stalls and may exhaust system resources leading
to a Denial of Service.",
      "recommendation": "Upgrade to version 3.13.0.",
      "references": "",
      "access": "public",
      "severity": "moderate",
      "cwe": "CWE-400",
      "metadata": {
        "module_type": "",
        "exploitability": 6,
        "affected_components": ""
      },
      "url": "https://npmjs.com/advisories/788"
    }
  },
  "muted": [],
  "metadata": {
    "vulnerabilities": {
      "info": 0,
      "low": 0,
      "moderate": 3,
      "high": 0,
      "critical": 0
    },
    "dependencies": 77,
    "devDependencies": 1542,
    "optionalDependencies": 0,
    "totalDependencies": 1619
  },
  "runId": "971192a5-28b1-4d79-be80-37223d041e4e"
}

Are you open to supporting node v6

My travis ci build is failing for node v6 because of a dangling comma in a function argument.

0.09s$ if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then audit-ci --moderate; fi
/home/travis/build/node-gh/gh/node_modules/audit-ci/lib/audit-ci-reporter.js:61
      );
      ^

This could be solved with a .prettierrc file setting:

{
    "trailingComma": "es5"
}

Would you be open to accepting a PR for this?

Thanks for your great work on this by the way. It's a fantastic idea!

Support Yarn

[email protected] introduced the yarn audit command. It functions differently than npm audit.

The expected behaviour is to use yarn audit and parse the result of the audit. It is not necessarily important to make the audit-ci report to look similar to the NPM equivalent report.

The NPM reporter should be separated from the Yarn reporter (issue #5). PR #15 is a sufficient starting point.

retry is not kicking in with npm 6.x

Looks like the error message is not matched, is this a known issue?

bartvde@bartvde-XPS-13-9360:~/planet/git/audit-ci$ git diff
diff --git a/lib/audit.js b/lib/audit.js
index 501ea59..62c042e 100644
--- a/lib/audit.js
+++ b/lib/audit.js
@@ -7,9 +7,9 @@ function audit(pm, config, reporter) {
   const RETRY_ERROR_MSG = {
     npm: `${
       config.registry
-        ? `npm ERR! audit Your configured registry (${config.registry}) `
+        ? `code ENOAUDIT: Your configured registry (${config.registry}) `
         : ''
-    }does not support audit requests`,
+    }may not support audit requests, or the audit endpoint may be temporarily unavailable.`,
     yarn: '503 Service Unavailable',
   };

Can't find package manager files (package.json, etc.) when using `--directory`

Steps for reproduction:

audit-ci -l --directory ./test/yarn-high/

Result:

Invocation of npm audit failed:
npm ERR! code EAUDITNOLOCK
npm ERR! audit Neither npm-shrinkwrap.json nor package-lock.json found: Cannot audit a project without a lockfile
npm ERR! audit Try creating one first with: npm i --package-lock-only
npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Quinn Turner\AppData\Roaming\npm-cache\_logs\2019-02-27T00_41_24_516Z-debug.log
Exiting...

Expected:
Valid audit

[Feature] Show whitelisted advisories and modules that were not found

audit-ci.json files that contain advisories (or modules) can become outdated when dependencies are updated. What once was a vulnerable package may not be anymore.

Proposition:

audit-ci -l --config audit-ci.json or equivalent command should output (via yellow console.warn) the advisories and modules that are whitelisted in the config that is not in the audit report.

Reasoning:

Advisories that have been addressed should not be left as residual fragments within the config file. They could lead to suppressing new advisories that have not been addressed properly.

audit-ci is generating a huge file that breaks our deploy to firebase

After we run:

yarn audit-ci --moderate

On CircleCI (node:10.15.3) we got a huge file named:

-rw-------   1 circleci circleci 1663508480 Mar 18 19:09 core.786.!usr!local!bin!node

This file gets included in the zip file we send to deploy to our cloud functions and we got an error because the zip file is too big. It goes from 350kb to 65 MB in our case.

[Bug] `child_process` success is depending on `stderr`

Description

if (stderr) {

To filter if an error happened, the argument _error should be check instead of error's stream (stderr). The reason is that stderr may have errors, but that doesn't mean the command execution completely failed. If it fails child_process will throw an Error and pass it in the error argument.

Screenshots

image

Expectations

Instead of using if (stderr) let's use if (_error).

Additional comments

As an extra protection layer, we should also wrap JSON.parse with a try-catch in case that the output fails. To don't depend completely on npm audit --json.

Migrate towards `spawn` instead of `exec`

See comments in #47 for more information regarding the decision behind using spawn instead of exec.

I have had difficulties in the past with spawn for displaying inappropriate errors due to uncaught exceptions (or rejections) in a Promise (see #45). That issue should be addressed, along with the spawn migration, in the same PR. Some work can also be done for #39.

Add support for whitelisting specific advisories

It would be nice to be able to whitelist specific advisories (by their id, cve, or other unique identifier).

For example, I got a critical advisory for the open package, but I feel safe whitelisting that specific advisory (since it's just a warning about injection attacks via unsanitized user input). But if open was hijacked and running malicious code, I wouldn't want to ignore that. But right now, my only option is totally ignore all advisories for that package.

Remove whitelisted module from JSON output

It would be nice if the output JSON didn't show information about the whitelisted module, or potentially introduce a new report type. It is a bit cumbersome to go through the JSON of vulnerabilities to find a newly introduced vulnerability when the output also contains the module that you have already "ignored". To reduce this noise we are using the summary report type, but that doesn't print out the failing module when a new vulnerability has been introduced.

If we can come up with a resolution to this I'm happy to create a PR!

pass-enoaudit flag passes integration even without registry returning ENOAUDIT

Test:

pass-enoaudit: true
critical: true

Expected Behavior:
If registry does not return ENOAUDIT, the expected behavior is the integration fails with error

    "vulnerabilities": {
      "info": 0,
      "low": 18,
      "moderate": 47,
      "high": 402,
      "critical": 1
    }
Failed security audit due to critical vulnerabilities.
Exiting...

Current Behavior:
Registry is not returning ENOAUDIT and audit-ci passes the integration even with critical vulnerabilities

    "vulnerabilities": {
      "info": 0,
      "low": 18,
      "moderate": 47,
      "high": 402,
      "critical": 1
    }
ACTION RECOMMENDED: An audit could not performed due to 5 audits that resulted in ENOAUDIT. Perform an audit manually and verify that no significant vulnerabilities exist before merging.
Passed npm security audit.

chicken vs egg

Please tell me if I'm missing something but isn't npm install --save-dev audit-ci also an attack vector since it runs npm install and installs all packages? Isn't the whole point to avoid running npm install until you verify packages are not compromised with npm audit?

So running npm install --save-dev audit-ci is unsafe. The safest path to installing packages is something like (see below)?

npm audit audit-ci  # fails because npm audit does not take a packages as argument
npm install -g audit-ci
audit-ci [your specific args]
npm ci

[Feature] Ignore specific path of vulnerability

Hello again :-)

I am using this project regularly and one thing bothers me a bit. When I have a vulnerability alert from a nested dependency that does not affect me and there is no upgrade possible, I have to ignore the advisory.
For instance, the braces dependency with advisory 786 is a dependency of jest so I am OK to ignore it. However, I will not be warned in the future if a dependency used in the production build uses braces and I will be exposed to a Regular Expression Denial of Service.

I would like to ignore path only and not global advisories. The package npm-audit-resolver (similar to audit-ci) does this for instance.

Thank you again for this package

What do you think about it? I am willing to write a pull request for this issue if you agree.

"-bash: audit-ci: command not found" on CircleCI

Running a CircleCI job in version 2 of CircleCi. Have the two commands, slightly modified from the Readme:

    - run: cd app && npm install --no-audit
    - run: cd app && audit-ci --moderate

When CircleCI executes the command it returns: "/bin/bash: audit-ci: command not found"

We are running node v10.15 and npm v6.9.

What am I missing? From what I understand the code makes a bash script available as audit-ci?

Consolidate the `npm-auditor` and `yarn-auditor` further

There's a ton of duplicated logic between the two auditors. This originated as a by-product from splitting between using spawn for yarn and exec for npm. This issue will be resolved when a significant proportion of the duplicated code is consolidated.

Request: remove a call to package registry

Summary of error

2.4.2 features a (undocumented, as far as I can tell) call to the npm registry to check the version of the audit-ci package. This causes opaque errors when using a private npm registry.

Details

I recently ran into a surprising error in two different repos, both of which used audit-ci on version 2.4. These repositories are configured to use my company's private package registry, which requires authentication.

Running audit-ci in one case failed with this error

circleci@85c52d082288:~/project$ yarn test-audit
yarn run v1.21.1
$ node ./node_modules/.bin/audit-ci --config .audit-ci.json --pass-enoaudit
running general audit
{"type":"error","data":"Received invalid response from npm."}
Unexpected end of JSON input
Exiting...
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

And another proceeded just fine.

Adding --verbose to the yarn info command in this library's 2.4.2 version showed me that the last line was a 401 from our private package registry. 2.4.0 and 2.4.1 don't have that call to check the self-version of the library - it was added in this commit

Suggested fix

There's a couple of options

  1. (my preference) Remove the yarn info call and establish this package's version via lookup of its package.json's version. This would mean users don't need to have authentication configured and would avoid a network call that (I think) can be avoided with a local filesystem lookup.
  2. Mark 2.4.2 as deprecated and version bump this library to 2.5, with a note in the changelog that 2.5 requires user authentication. And maybe handle authentication errors?

Introduce AppVeyor tests and documentation

AppVeyor is another excellent CI environment that we should explicitly support and test!

Documentation changes should be made for integration, similar to how Travis-CI and CircleCI documentation exists.

We should also introduce AppVeyor tests into our PRs if possible.

[Feature]: Ignore devDependencies

Hi, this tools looks great and I hope to replace some home grown stuff I wrote.

would it be useful to have an "ignore dev" option? So vulnerabilities in dev dependencies would be ignored. For example:

audit-ci --high fails on vulnerabilities that are high or critical
audit-ci --high-prod would only fail only on non-dev dependencies that are high or critical.

I'm curious what you think! Thank you.

append custom message to the report

Summary report gives high level information about why the audit failed and this is great. But a lot of developers looking at it are not sure what to do next and how to fix it.
It would be great to have an option to append custom message to the generated report which points the developers to the resources they need to refer to if audit-ci test failed

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.