tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

【node.js】npm@6にしたらnpm auditでpackageの脆弱性をチェックできるようになったメモ

はじめに

npmコマンドを叩いた際に、@6.x.xにあげてねと言われました。

言われれるがままにあげてみたら
npm auditも行えと言われてなんだこれ..と思って調べた自分用メモです。

f:id:tweeeety:20180615185946j:plain

画像元

アジェンダ

  1. npm auditとは
  2. "npm auditしてね"までの流れ
  3. npm auditの見方と対応の流れ
  4. npm auditの使い方

1. npm auditとは

npm auditは、
npm install/node_modules配下にインストールしたpackageの脆弱性をチェックしてくれるものです。

以下、参考サイトからの引用です。

liftsecurity.ioという企業が持っていた
セキュリティノウハウをnpm側が取得したことにより
packageの脆弱性のチェックができるようになった  

2. "npm auditしてね"までの流れ

npm runスクリプト
# npm runスクリプトを走らせると
# @6.x.xにあげてねと言われる
$ npm run hoge

> hoge@1.0.0 hoge /Users/tweeeety/Hoge
> gulp

[14:52:35] Using gulpfile ~/Hoge/gulpfile.js
(node:9422) [DEP0016] DeprecationWarning: 'root' is deprecated, use 'global'
~ 省略 ~ 
[14:52:35] Finished 'svg' after 119 ms


   ╭─────────────────────────────────────╮
   │                                     │
   │   Update available 5.6.0 → 6.1.0    │
   │     Run npm i -g npm to update      │
   │                                     │
   ╰─────────────────────────────────────╯
素直にあげる
# 一応version確認
$ npm -v
5.6.0

# あげる
$ npm i -g npm
/Users/tweeeety/.nodebrew/node/v8.11.0/bin/npm -> /Users/tweeeety/.nodebrew/node/v8.11.0/lib/node_modules/npm/bin/npm-cli.js
/Users/tweeeety/.nodebrew/node/v8.11.0/bin/npx -> /Users/tweeeety/.nodebrew/node/v8.11.0/lib/node_modules/npm/bin/npx-cli.js
+ npm@6.1.0
added 247 packages, removed 41 packages and updated 129 packages in 15.683s
npm installすると"npm auditしてみ"と言われる
# npmのversionあげたので念のためnpm install
$ npm install
audited 3268 packages in 5.548s
found 6 vulnerabilities (2 low, 4 high)
  run `npm audit fix` to fix them, or `npm audit` for details
  # `npm auditしてね`と言われる

3. npm auditの見方と対応の流れ

npm auditの使い方はいくつかあるようですが、
npm auditとだけうつとチェックと結果のレポートを表示してくれます。

まずは見て見る

$ npm audit

                       === npm audit security report ===

# Run  npm install --save-dev gulp@4.0.0  to resolve 5 vulnerabilities
SEMVER WARNING: Recommended action is a potentially breaking change
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp [dev]                                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-stream > glob > minimatch             │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/118                       │
└───────────────┴──────────────────────────────────────────────────────────────┘


┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp [dev]                                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-stream > minimatch                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/118                       │
└───────────────┴──────────────────────────────────────────────────────────────┘


┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp [dev]                                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-watcher > gaze > globule > glob >     │
│               │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/118                       │
└───────────────┴──────────────────────────────────────────────────────────────┘


┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Regular Expression Denial of Service                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ minimatch                                                    │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp [dev]                                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-watcher > gaze > globule > minimatch  │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/118                       │
└───────────────┴──────────────────────────────────────────────────────────────┘


┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Low           │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ lodash                                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ gulp [dev]                                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ gulp > vinyl-fs > glob-watcher > gaze > globule > lodash     │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/577                       │
└───────────────┴──────────────────────────────────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────────────┐
│                                Manual Review                                 │
│            Some vulnerabilities require your attention to resolve            │
│                                                                              │
│         Visit https://go.npm.me/audit-guide for additional guidance          │
└──────────────────────────────────────────────────────────────────────────────┘
  2   "name": "hoge",
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Low           │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ lodash                                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=4.17.5                                                     │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ diff-json [dev]                                              │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ diff-json > lodash                                           │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/577                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
found 6 vulnerabilities (2 low, 4 high) in 3268 scanned packages
  5 vulnerabilities require semver-major dependency updates.
  1 vulnerability requires manual review. See the full report for details.

最初にみるべきは一番下のこれです。

found 6 vulnerabilities (2 low, 4 high) in 3268 scanned packages 5 vulnerabilities require semver-major dependency updates. 1 vulnerability requires manual review. See the full report for details.

6個の脆弱性がみつかって、
2個は低レベル、4つは高レベルの脆弱性だよ、と。

やべーじゃん...

対応してみる

各レポートの上にこんな記載があれば、
それを打つことで解決できそうだよと教えてくれています。

# Run npm install --save-dev gulp@4.0.0 to resolve 5 vulnerabiliti SEMVER WARNING: Recommended action is a potentially breaking change

ということで試して見ます。

# 言われるがままに対応してみる
$ npm install --save-dev gulp@4.0.0
+ gulp@4.0.0
added 97 packages from 80 contributors, removed 29 packages, updated 59 packages and audited 6754 packages in 14.622s
found 1 low severity vulnerability
  run `npm audit fix` to fix them, or `npm audit` for details


# 再度脆弱性チェックを行う
# 1つに減っている!
$ npm audit

                       === npm audit security report ===

┌──────────────────────────────────────────────────────────────────────────────┐
│                                Manual Review                                 │
│            Some vulnerabilities require your attention to resolve            │
│                                                                              │
│         Visit https://go.npm.me/audit-guide for additional guidance          │
└──────────────────────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Low           │ Prototype Pollution                                          │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ lodash                                                       │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >=4.17.5                                                     │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ diff-json [dev]                                              │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ diff-json > lodash                                           │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/577                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
found 1 low severity vulnerability in 6754 scanned packages
  1 vulnerability requires manual review. See the full report for details.

4. npm auditの使い方

いくつかだけ例をあげます

npm aduit
$ npm audit

# レポートが表示される
npm audit --json

--jsonオプションをつけることで、
レポートをjson形式で表示してくれます。

先ほどの例で--jsonをつけた場合のレポート表示です。

$ npm audit --json
{
  "actions": [
    {
      "action": "install",
      "module": "gulp",
      "target": "4.0.0",
      "isMajor": true,
      "resolves": [
        {
          "id": 118,
          "path": "gulp>vinyl-fs>glob-stream>glob>minimatch",
          "dev": true,
          "optional": false,
          "bundled": false
        },
        {
          "id": 118,
          "path": "gulp>vinyl-fs>glob-stream>minimatch",
          "dev": true,
          "optional": false,
          "bundled": false
        },
        {
          "id": 118,
          "path": "gulp>vinyl-fs>glob-watcher>gaze>globule>glob>minimatch",
          "dev": true,
          "optional": false,
          "bundled": false
        },
        {
          "id": 118,
          "path": "gulp>vinyl-fs>glob-watcher>gaze>globule>minimatch",
          "dev": true,
          "optional": false,
          "bundled": false
        },
        {
          "id": 577,
          "path": "gulp>vinyl-fs>glob-watcher>gaze>globule>lodash",
          "dev": true,
          "optional": false,
          "bundled": false
        }
      ]
    },
    {
      "action": "review",
      "module": "lodash",
      "resolves": [
        {
          "id": 577,
          "path": "diff-json>lodash",
          "dev": true,
          "optional": false,
          "bundled": false
        }
      ]
    }
  ],
  "advisories": {
    "118": {
      "findings": [
        {
          "version": "2.0.10",
          "paths": [
            "gulp>vinyl-fs>glob-stream>glob>minimatch",
            "gulp>vinyl-fs>glob-stream>minimatch"
          ],
          "dev": true,
          "optional": false,
          "bundled": false
        },
        {
          "version": "0.2.14",
          "paths": [
            "gulp>vinyl-fs>glob-watcher>gaze>globule>glob>minimatch",
            "gulp>vinyl-fs>glob-watcher>gaze>globule>minimatch"
          ],
          "dev": true,
          "optional": false,
          "bundled": false
        }
      ],
      "id": 118,
      "created": "2016-05-25T16:37:20.000Z",
      "updated": "2018-03-01T21:58:01.072Z",
      "deleted": null,
      "title": "Regular Expression Denial of Service",
      "found_by": {
        "name": "Nick Starke"
      },
      "reported_by": {
        "name": "Nick Starke"
      },
      "module_name": "minimatch",
      "cves": [
        "CVE-2016-10540"
      ],
      "vulnerable_versions": "<=3.0.1",
      "patched_versions": ">=3.0.2",
      "overview": "Affected versions of `minimatch` are vulnerable to regular expression denial of service attacks when user input is passed into the `pattern` argument of `minimatch(path, pattern)`.\n\n\n## Proof of Concept\n```\nvar minimatch = require(“minimatch”);\n\n// utility function for generating long strings\nvar genstr = function (len, chr) {\n  var result = “”;\n  for (i=0; i<=len; i++) {\n    result = result + chr;\n  }\n  return result;\n}\n\nvar exploit = “[!” + genstr(1000000, “\\\\”) + “A”;\n\n// minimatch exploit.\nconsole.log(“starting minimatch”);\nminimatch(“foo”, exploit);\nconsole.log(“finishing minimatch”);\n```",
      "recommendation": "Update to version 3.0.2 or later.",
      "references": "",
      "access": "public",
      "severity": "high",
      "cwe": "CWE-400",
      "metadata": {
        "module_type": "Multi.Library",
        "exploitability": 4,
        "affected_components": "Internal::Code::Function::minimatch({type:'args', key:0, vector:{type:'string'}})"
      },
      "url": "https://nodesecurity.io/advisories/118"
    },
    "577": {
      "findings": [
        {
          "version": "2.4.2",
          "paths": [
            "diff-json>lodash"
          ],
          "dev": true,
          "optional": false,
          "bundled": false
        },
        {
          "version": "1.0.2",
          "paths": [
            "gulp>vinyl-fs>glob-watcher>gaze>globule>lodash"
          ],
          "dev": true,
          "optional": false,
          "bundled": false
        }
      ],
      "id": 577,
      "created": "2018-04-24T14:27:02.796Z",
      "updated": "2018-04-24T14:27:13.049Z",
      "deleted": null,
      "title": "Prototype Pollution",
      "found_by": {
        "name": "Olivier Arteau (HoLyVieR)"
      },
      "reported_by": {
        "name": "Olivier Arteau (HoLyVieR)"
      },
      "module_name": "lodash",
      "cves": [
        "CVE-2018-3721"
      ],
      "vulnerable_versions": "<4.17.5",
      "patched_versions": ">=4.17.5",
      "overview": "Versions of `lodash` before 4.17.5 are vulnerable to prototype pollution. \n\nThe vulnerable functions are 'defaultsDeep', 'merge', and 'mergeWith' which allow a malicious user to modify the prototype of `Object` via `__proto__` causing the addition or modification of an existing property that will exist on all objects.\n\n",
      "recommendation": "Update to version 4.17.5 or later.",
      "references": "- [HackerOne Report](https://hackerone.com/reports/310443)",
      "access": "public",
      "severity": "low",
      "cwe": "CWE-471",
      "metadata": {
        "module_type": "",
        "exploitability": 1,
        "affected_components": ""
      },
      "url": "https://nodesecurity.io/advisories/577"
    }
  },
  "muted": [],
  "metadata": {
    "vulnerabilities": {
      "info": 0,
      "low": 2,
      "moderate": 0,
      "high": 4,
      "critical": 0
    },
    "dependencies": 0,
    "devDependencies": 3268,
    "optionalDependencies": 196,
    "totalDependencies": 3268
  },
  "runId": "91d63b40-7d49-494e-a020-48ac0af8ffcc"
}
npm audit fix

これはやってみるとわかりますが、
示唆してくれた改善案があればそれを実行してくれるものです。

先ほどの例でいうと
npm audit fix
を打つと
npm install --save-dev gulp@4.0.0
を行なってくれます。

# 例にあげた最初の状態
$ npm audit

~ 省略 ~ 

found 6 vulnerabilities (2 low, 4 high) in 3268 scanned packages
  5 vulnerabilities require semver-major dependency updates.
  1 vulnerability requires manual review. See the full report for details.

# 打って見る
$ npm audit fix
up to date in 2.72s
fixed 0 of 6 vulnerabilities in 3268 scanned packages
  1 vulnerability required manual review and could not be updated
  1 package update for 5 vulns involved breaking changes
  (use `npm audit fix --force` to install breaking changes; or do it by hand)

# 再度チェック
# 結果は1つに減っている
$ npm audit

~ 省略 ~ 

found 1 low severity vulnerability in 6754 scanned packages
  1 vulnerability requires manual review. See the full report for details.
その他

そのほかは公式をご参照あれ。
https://docs.npmjs.com/cli/audit

また、以下の動画でも詳しく解説されていました。
https://www.youtube.com/watch?v=QflNpG3VuGY

おわり

packageの脆弱性のチェックだけじゃなくて
対応コマンドまで表示してくれるのは嬉しいですね!!
\(^o^)/