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

Bug#977735: buster-pu: package node-ini/1.3.5-1+deb10u1



Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu

[ Reason ]
node-ini is vulnearable to CVE-2020-7788: if an attacker submits a malicious
INI file to an application that parses it with ini.parse, they will pollute
the prototype on the application. This can be exploited further depending
on the context. (#977718)

[ Impact ]
Little vulnerability

[ Tests ]
Patch includes a test

[ Risks ]
Change just adds 2 checks, No risk.

[ Checklist ]
  [X] *all* changes are documented in the d/changelog
  [X] I reviewed all changes and I approve them
  [X] attach debdiff against the package in (old)stable
  [X] the issue is verified as fixed in unstable

[ Changes ]
2 checks to avoid prototype pollution
diff --git a/debian/changelog b/debian/changelog
index 4d4fc30..a153918 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+node-ini (1.3.5-1+deb10u1) buster; urgency=medium
+
+  * Team upload
+  * Do not allow invalid hazardous string as section name
+    (Closes: #977718, CVE-2020-7788)
+
+ -- Xavier Guimard <yadd@debian.org>  Sat, 19 Dec 2020 20:48:36 +0100
+
 node-ini (1.3.5-1) unstable; urgency=medium
 
   * Team Upload
diff --git a/debian/patches/CVE-2020-7788.patch b/debian/patches/CVE-2020-7788.patch
new file mode 100644
index 0000000..54f5bbe
--- /dev/null
+++ b/debian/patches/CVE-2020-7788.patch
@@ -0,0 +1,87 @@
+Description: do not allow invalid hazardous string as section name
+Author: isaacs <i@izs.me>
+Bug: https://snyk.io/vuln/SNYK-JS-INI-1048974
+Bug-Debian: https://bugs.debian.org/977718
+Forwarded: not-needed
+Reviewed-By: Xavier Guimard <yadd@debian.org>
+Last-Update: 2020-12-19
+
+--- a/ini.js
++++ b/ini.js
+@@ -80,6 +80,12 @@
+     if (!match) return
+     if (match[1] !== undefined) {
+       section = unsafe(match[1])
++      if (section === '__proto__') {
++        // not allowed
++        // keep parsing the section, but don't attach it.
++        p = {}
++        return
++      }
+       p = out[section] = out[section] || {}
+       return
+     }
+@@ -94,6 +100,7 @@
+     // Convert keys with '[]' suffix to an array
+     if (key.length > 2 && key.slice(-2) === '[]') {
+       key = key.substring(0, key.length - 2)
++      if (key === '__proto__') return
+       if (!p[key]) {
+         p[key] = []
+       } else if (!Array.isArray(p[key])) {
+@@ -125,6 +132,7 @@
+     var l = parts.pop()
+     var nl = l.replace(/\\\./g, '.')
+     parts.forEach(function (part, _, __) {
++      if (part === '__proto__') return
+       if (!p[part] || typeof p[part] !== 'object') p[part] = {}
+       p = p[part]
+     })
+--- /dev/null
++++ b/test/proto.js
+@@ -0,0 +1,45 @@
++var ini = require('../')
++var t = require('tap')
++
++var data = `
++__proto__ = quux
++foo = baz
++[__proto__]
++foo = bar
++[other]
++foo = asdf
++[kid.__proto__.foo]
++foo = kid
++[arrproto]
++hello = snyk
++__proto__[] = you did a good job
++__proto__[] = so you deserve arrays
++thanks = true
++`
++var res = ini.parse(data)
++t.deepEqual(res, {
++  foo: 'baz',
++  other: {
++    foo: 'asdf',
++  },
++  kid: {
++    foo: {
++      foo: 'kid',
++    },
++  },
++  arrproto: {
++    hello: 'snyk',
++    thanks: true,
++  },
++})
++t.equal(res.__proto__, Object.prototype)
++t.equal(res.kid.__proto__, Object.prototype)
++t.equal(res.kid.foo.__proto__, Object.prototype)
++t.equal(res.arrproto.__proto__, Object.prototype)
++t.equal(Object.prototype.foo, undefined)
++t.equal(Object.prototype[0], undefined)
++t.equal(Object.prototype['0'], undefined)
++t.equal(Object.prototype[1], undefined)
++t.equal(Object.prototype['1'], undefined)
++t.equal(Array.prototype[0], undefined)
++t.equal(Array.prototype[1], undefined)
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..c281569
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1 @@
+CVE-2020-7788.patch

Reply to: