[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#947172: marked as done (buster-pu: package npm/5.8.0+ds6-4+deb10u1)



Your message dated Sat, 09 May 2020 11:53:52 +0100
with message-id <fd7fa4d56896c35aab49a5a51cb69727dc60e87a.camel@adam-barratt.org.uk>
and subject line Closing requests included in 10.4 point release
has caused the Debian Bug report #947172,
regarding buster-pu: package npm/5.8.0+ds6-4+deb10u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
947172: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=947172
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu

Hi,

npm is vulnerable to some CVEs (CVE-2019-16775, CVE-2019-16776,
CVE-2019-16777). This patch groups patches from differents sub modules
affected and add a new module (npm-normalize-package-bin package) used
by these fixes.

After discussion with security team, these CVEs will be tagged as
no-dsa.

Cheers,
Xavier
diff --git a/debian/changelog b/debian/changelog
index 85e9028..d7b986f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+npm (5.8.0+ds6-4+deb10u1) buster; urgency=medium
+
+  * Add patches to fix arbitrary path access
+    (Closes: CVE-2019-16775, CVE-2019-16776, CVE-2019-16777)
+
+ -- Xavier Guimard <yadd@debian.org>  Sun, 15 Dec 2019 16:19:02 +0100
+
 npm (5.8.0+ds6-4) unstable; urgency=medium
 
   * Team upload
diff --git a/debian/patches/CVE-2019-16775-add-npm-normalize-package-bin.diff b/debian/patches/CVE-2019-16775-add-npm-normalize-package-bin.diff
new file mode 100644
index 0000000..a3c7b45
--- /dev/null
+++ b/debian/patches/CVE-2019-16775-add-npm-normalize-package-bin.diff
@@ -0,0 +1,167 @@
+Description: Add npm-normalize-package-bin package
+ Needed to CVE-2019-16775 fix
+Author: isaacs
+Bug: https://github.com/npm/cli/security/advisories/GHSA-x8qc-rrcw-4r46
+Forwarded: not-needed
+Reviewed-By: Xavier Guimard <yadd@debian.org>
+Last-Update: 2019-12-15
+
+--- /dev/null
++++ b/node_modules/npm-normalize-package-bin/LICENSE
+@@ -0,0 +1,15 @@
++The ISC License
++
++Copyright (c) npm, Inc.
++
++Permission to use, copy, modify, and/or distribute this software for any
++purpose with or without fee is hereby granted, provided that the above
++copyright notice and this permission notice appear in all copies.
++
++THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
++IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+--- /dev/null
++++ b/node_modules/npm-normalize-package-bin/README.md
+@@ -0,0 +1,14 @@
++# npm-normalize-package-bin
++
++Turn any flavor of allowable package.json bin into a normalized object.
++
++## API
++
++```js
++const normalize = require('npm-normalize-package-bin')
++const pkg = {name: 'foo', bin: 'bar'}
++console.log(normalize(pkg)) // {name:'foo', bin:{foo: 'bar'}}
++```
++
++Also strips out weird dots and slashes to prevent accidental and/or
++malicious bad behavior when the package is installed.
+--- /dev/null
++++ b/node_modules/npm-normalize-package-bin/index.js
+@@ -0,0 +1,60 @@
++// pass in a manifest with a 'bin' field here, and it'll turn it
++// into a properly santized bin object
++const {join, basename} = require('path')
++
++const normalize = pkg =>
++  !pkg.bin ? removeBin(pkg)
++  : typeof pkg.bin === 'string' ? normalizeString(pkg)
++  : Array.isArray(pkg.bin) ? normalizeArray(pkg)
++  : typeof pkg.bin === 'object' ? normalizeObject(pkg)
++  : removeBin(pkg)
++
++const normalizeString = pkg => {
++  if (!pkg.name)
++    return removeBin(pkg)
++  pkg.bin = { [pkg.name]: pkg.bin }
++  return normalizeObject(pkg)
++}
++
++const normalizeArray = pkg => {
++  pkg.bin = pkg.bin.reduce((acc, k) => {
++    acc[basename(k)] = k
++    return acc
++  }, {})
++  return normalizeObject(pkg)
++}
++
++const removeBin = pkg => {
++  delete pkg.bin
++  return pkg
++}
++
++const normalizeObject = pkg => {
++  const orig = pkg.bin
++  const clean = {}
++  let hasBins = false
++  Object.keys(orig).forEach(binKey => {
++    const base = join('/', basename(binKey.replace(/\\|:/g, '/'))).substr(1)
++
++    if (typeof orig[binKey] !== 'string' || !base)
++      return
++
++    const binTarget = join('/', orig[binKey])
++      .replace(/\\/g, '/').substr(1)
++
++    if (!binTarget)
++      return
++
++    clean[base] = binTarget
++    hasBins = true
++  })
++
++  if (hasBins)
++    pkg.bin = clean
++  else
++    delete pkg.bin
++
++  return pkg
++}
++
++module.exports = normalize
+--- /dev/null
++++ b/node_modules/npm-normalize-package-bin/package.json
+@@ -0,0 +1,58 @@
++{
++  "_from": "npm-normalize-package-bin",
++  "_id": "npm-normalize-package-bin@1.0.1",
++  "_inBundle": false,
++  "_integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==",
++  "_location": "/npm-normalize-package-bin",
++  "_phantomChildren": {},
++  "_requested": {
++    "type": "tag",
++    "registry": true,
++    "raw": "npm-normalize-package-bin",
++    "name": "npm-normalize-package-bin",
++    "escapedName": "npm-normalize-package-bin",
++    "rawSpec": "",
++    "saveSpec": null,
++    "fetchSpec": "latest"
++  },
++  "_requiredBy": [
++    "#USER",
++    "/"
++  ],
++  "_resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz";,
++  "_shasum": "6e79a41f23fd235c0623218228da7d9c23b8f6e2",
++  "_spec": "npm-normalize-package-bin",
++  "_where": "/tmp/tt",
++  "author": {
++    "name": "Isaac Z. Schlueter",
++    "email": "i@izs.me",
++    "url": "https://izs.me";
++  },
++  "bugs": {
++    "url": "https://github.com/npm/npm-normalize-package-bin/issues";
++  },
++  "bundleDependencies": false,
++  "deprecated": false,
++  "description": "Turn any flavor of allowable package.json bin into a normalized object",
++  "devDependencies": {
++    "tap": "^14.10.2"
++  },
++  "homepage": "https://github.com/npm/npm-normalize-package-bin#readme";,
++  "license": "ISC",
++  "name": "npm-normalize-package-bin",
++  "repository": {
++    "type": "git",
++    "url": "git+https://github.com/npm/npm-normalize-package-bin.git";
++  },
++  "scripts": {
++    "postpublish": "git push origin --follow-tags",
++    "postversion": "npm publish",
++    "preversion": "npm test",
++    "snap": "tap",
++    "test": "tap"
++  },
++  "tap": {
++    "check-coverage": true
++  },
++  "version": "1.0.1"
++}
diff --git a/debian/patches/CVE-2019-16775-bin-links.diff b/debian/patches/CVE-2019-16775-bin-links.diff
new file mode 100644
index 0000000..5a2f946
--- /dev/null
+++ b/debian/patches/CVE-2019-16775-bin-links.diff
@@ -0,0 +1,60 @@
+Description: sanitize and validate bin and man link targets
+ Part of CVE-2019-16776 fix
+Author: isaacs
+Origin: upstream, https://github.com/npm/bin-links/commit/25a34f9
+Bug: https://github.com/npm/cli/security/advisories/GHSA-x8qc-rrcw-4r46
+Forwarded: not-needed
+Reviewed-By: Xavier Guimard <yadd@debian.org>
+Last-Update: 2019-12-15
+
+--- a/node_modules/bin-links/index.js
++++ b/node_modules/bin-links/index.js
+@@ -12,10 +12,12 @@
+ const chmod = BB.promisify(fs.chmod)
+ const Transform = require('stream').Transform
+ const fsWriteStreamAtomic = require('fs-write-stream-atomic')
++const normalize = require('npm-normalize-package-bin')
+ 
+ module.exports = BB.promisify(binLinks)
+ 
+ function binLinks (pkg, folder, global, opts, cb) {
++  pkg = normalize(pkg)
+   // if it's global, and folder is in {prefix}/node_modules,
+   // then bins are in {prefix}/bin
+   // otherwise, then bins are in folder/../.bin
+@@ -107,6 +109,12 @@
+     var dest = path.resolve(binRoot, bin)
+     var src = path.resolve(folder, pkg.bin[bin])
+ 
++    /* istanbul ignore if - that unpossible */
++    if (src.indexOf(folder) !== 0) {
++      throw new Error('invalid bin entry for package ' +
++        pkg._id + '. key=' + bin + ', value=' + pkg.bin[bin])
++    }
++
+     linkBin(src, dest, linkOpts, function (er) {
+       if (er) return cb(er)
+       // bins should always be executable.
+@@ -157,7 +165,8 @@
+   // make sure that the mans are unique.
+   // otherwise, if there are dupes, it'll fail with EEXIST
+   var set = pkg.man.reduce(function (acc, man) {
+-    acc[path.basename(man)] = man
++    const cleanMan = path.join('/', man).replace(/\\|:/g, '/').substr(1)
++    acc[path.basename(man)] = cleanMan
+     return acc
+   }, {})
+   pkg.man = pkg.man.filter(function (man) {
+@@ -180,6 +189,12 @@
+     var sxn = parseMan[2]
+     var bn = path.basename(stem)
+     var manSrc = path.resolve(folder, man)
++    /* istanbul ignore if - that unpossible */
++    if (manSrc.indexOf(folder) !== 0) {
++      throw new Error('invalid man entry for package ' +
++        pkg._id + '. man=' + manSrc)
++    }
++
+     var manDest = path.join(manRoot, 'man' + sxn, bn)
+ 
+     linkIfExists(manSrc, manDest, getLinkOpts(opts, gtop && folder), cb)
diff --git a/debian/patches/CVE-2019-16775-npm-packlist.diff b/debian/patches/CVE-2019-16775-npm-packlist.diff
new file mode 100644
index 0000000..f1b7a08
--- /dev/null
+++ b/debian/patches/CVE-2019-16775-npm-packlist.diff
@@ -0,0 +1,29 @@
+Description: sanitize and normalize package bin field
+ Part of CVE-2019-16776 fix
+Author: isaacs
+Origin: upstream, https://github.com/npm/npm-packlist/commit/ec4d56e
+Bug: https://github.com/npm/cli/security/advisories/GHSA-x8qc-rrcw-4r46
+Forwarded: not-needed
+Reviewed-By: Xavier Guimard <yadd@debian.org>
+Last-Update: 2019-12-15
+
+--- a/node_modules/npm-packlist/index.js
++++ b/node_modules/npm-packlist/index.js
+@@ -17,6 +17,8 @@
+ const packageNecessaryRules = Symbol('package-necessary-rules')
+ const path = require('path')
+ 
++const normalizePackageBin = require('npm-normalize-package-bin')
++
+ const defaultRules = [
+   '.npmignore',
+   '.gitignore',
+@@ -154,7 +156,7 @@
+   onReadIgnoreFile (file, data, then) {
+     if (file === 'package.json')
+       try {
+-        this.onPackageJson(file, JSON.parse(data), then)
++        this.onPackageJson(file, normalizePackageBin(JSON.parse(data)), then)
+       } catch (er) {
+         // ignore package.json files that are not json
+         then()
diff --git a/debian/patches/CVE-2019-16775-pacote.diff b/debian/patches/CVE-2019-16775-pacote.diff
new file mode 100644
index 0000000..bb52001
--- /dev/null
+++ b/debian/patches/CVE-2019-16775-pacote.diff
@@ -0,0 +1,58 @@
+Description: sanitize and normalize package bin field
+ Part of CVE-2019-16776 fix
+Author: isaacs
+Origin: upstream, https://github.com/npm/pacote/commit/6f229f7
+Bug: https://github.com/npm/cli/security/advisories/GHSA-x8qc-rrcw-4r46
+Forwarded: not-needed
+Reviewed-By: Xavier Guimard <yadd@debian.org>
+Last-Update: 2019-12-15
+
+--- a/node_modules/pacote/lib/fetchers/directory.js
++++ b/node_modules/pacote/lib/fetchers/directory.js
+@@ -8,6 +8,7 @@
+ const path = require('path')
+ const pipe = BB.promisify(require('mississippi').pipe)
+ const through = require('mississippi').through
++const normalizePackageBin = require('npm-normalize-package-bin')
+ 
+ const readFileAsync = BB.promisify(require('fs').readFile)
+ 
+@@ -46,7 +47,7 @@
+       } else {
+         return pkg
+       }
+-    })
++    }).then(pkg => normalizePackageBin(pkg))
+   },
+ 
+   // As of npm@5, the npm installer doesn't pack + install directories: it just
+--- a/node_modules/pacote/lib/finalize-manifest.js
++++ b/node_modules/pacote/lib/finalize-manifest.js
+@@ -13,6 +13,7 @@
+ const pipe = BB.promisify(require('mississippi').pipe)
+ const ssri = require('ssri')
+ const tar = require('tar')
++const normalizePackageBin = require('npm-normalize-package-bin')
+ 
+ // `finalizeManifest` takes as input the various kinds of manifests that
+ // manifest handlers ('lib/fetchers/*.js#manifest()') return, and makes sure
+@@ -102,17 +103,8 @@
+   this._shrinkwrap = pkg._shrinkwrap || fromTarball._shrinkwrap || null
+   this.bin = pkg.bin || fromTarball.bin || null
+ 
+-  if (this.bin && Array.isArray(this.bin)) {
+-    // Code yanked from read-package-json.
+-    const m = (pkg.directories && pkg.directories.bin) || '.'
+-    this.bin = this.bin.reduce((acc, mf) => {
+-      if (mf && mf.charAt(0) !== '.') {
+-        const f = path.basename(mf)
+-        acc[f] = path.join(m, mf)
+-      }
+-      return acc
+-    }, {})
+-  }
++  // turn arrays and strings into a legit object, strip out bad stuff
++  normalizePackageBin(this)
+ 
+   this._id = null
+ 
diff --git a/debian/patches/series b/debian/patches/series
index c29dbfe..95031c5 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -9,3 +9,7 @@
 2014_remove_readable_stream.patch
 2015_use_system_libnpx_1.patch
 new-lru-cache.patch
+CVE-2019-16775-bin-links.diff
+CVE-2019-16775-npm-packlist.diff
+CVE-2019-16775-pacote.diff
+CVE-2019-16775-add-npm-normalize-package-bin.diff

--- End Message ---
--- Begin Message ---
Package: release.debian.org
Version: 10.4

Hi,

Each of the uploads referred to by these bugs was included in today's
stable point release.

Regards,

Adam

--- End Message ---

Reply to: