Package: release.debian.org Severity: normal Tags: buster User: release.debian....@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 <y...@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 <y...@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