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

Bug#987042: buster-pu: package node-handlebars/4.1.0-1+deb10u3



Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu
X-Debbugs-Cc: utkarsh@debian.org

[ Reason ]
node-handlebars is vulnerable to Arbitrary Code Execution and Remote
Code Execution (CVE-2019-20920 and CVE-2021-23369)

[ Impact ]
Medium vulnerabilities

[ Tests ]
Sadly there are no test launched in Buster even if upstream added some
checks

[ Risks ]
Medium risk, upstream patches were applied without changes

[ 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 ]
More checks for given arguments

Cheers,
Yadd
diff --git a/debian/changelog b/debian/changelog
index e49c409..e55d497 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+node-handlebars (3:4.1.0-1+deb10u3) buster; urgency=medium
+
+  * Team upload
+  * Fix arbitrary code execution (Closes: CVE-2019-20920)
+  * Fix remote code execution (Closes: CVE-2021-23369)
+
+ -- Yadd <yadd@debian.org>  Fri, 16 Apr 2021 10:31:24 +0200
+
 node-handlebars (3:4.1.0-1+deb10u2) buster; urgency=medium
 
   * Fix regression introduced in 3:4.1.0-1+deb10u1
diff --git a/debian/patches/CVE-2019-20920.patch b/debian/patches/CVE-2019-20920.patch
new file mode 100644
index 0000000..54e3bd3
--- /dev/null
+++ b/debian/patches/CVE-2019-20920.patch
@@ -0,0 +1,114 @@
+Description: fix for CVE-2019-20920
+Author: Nils Knappmeier <github@knappi.org>
+Origin: upstream, https://github.com/handlebars-lang/handlebars.js/commit/1988878
+Bug: https://snyk.io/vuln/SNYK-JS-HANDLEBARS-534478
+Forwarded: not-needed
+Reviewed-By: Xavier Guimard <yadd@debian.org>
+Last-Update: 2020-10-12
+
+--- a/lib/handlebars/compiler/compiler.js
++++ b/lib/handlebars/compiler/compiler.js
+@@ -56,7 +56,7 @@
+ 
+     // These changes will propagate to the other compiler components
+     let knownHelpers = options.knownHelpers;
+-    options.knownHelpers = {
++    options.knownHelpers = extend(Object.create(null), {
+       'helperMissing': true,
+       'blockHelperMissing': true,
+       'each': true,
+@@ -65,15 +65,7 @@
+       'with': true,
+       'log': true,
+       'lookup': true
+-    };
+-    if (knownHelpers) {
+-      // the next line should use "Object.keys", but the code has been like this a long time and changing it, might
+-      // cause backwards-compatibility issues... It's an old library...
+-      // eslint-disable-next-line guard-for-in
+-      for (let name in knownHelpers) {
+-          this.options.knownHelpers[name] = knownHelpers[name];
+-      }
+-    }
++    }, options.knownHelpers);
+ 
+     return this.accept(program);
+   },
+--- a/lib/handlebars/compiler/javascript-compiler.js
++++ b/lib/handlebars/compiler/javascript-compiler.js
+@@ -2,6 +2,7 @@
+ import Exception from '../exception';
+ import {isArray} from '../utils';
+ import CodeGen from './code-gen';
++import {dangerousPropertyRegex} from '../helpers/lookup';
+ 
+ function Literal(value) {
+   this.value = value;
+@@ -13,8 +14,9 @@
+   // PUBLIC API: You can override these methods in a subclass to provide
+   // alternative compiled forms for name lookup and buffering semantics
+   nameLookup: function(parent, name/* , type*/) {
+-    if (name === 'constructor') {
+-      return ['(', parent, '.propertyIsEnumerable(\'constructor\') ? ', parent, '.constructor : undefined', ')'];
++    if (dangerousPropertyRegex.test(name)) {
++      const isEnumerable = [ this.aliasable('container.propertyIsEnumerable'), '.call(', parent, ',', JSON.stringify(name), ')'];
++      return ['(', isEnumerable, '?', _actualLookup(), ' : undefined)'];
+     }
+     if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
+       return [parent, '.', name];
+--- a/lib/handlebars/helpers/lookup.js
++++ b/lib/handlebars/helpers/lookup.js
+@@ -1,5 +1,13 @@
++export const dangerousPropertyRegex = /^(constructor|__defineGetter__|__defineSetter__|__lookupGetter__|__proto__)$/;
++
+ export default function(instance) {
+   instance.registerHelper('lookup', function(obj, field) {
+-    return obj && obj[field];
++    if (!obj) {
++      return obj;
++    }
++    if (dangerousPropertyRegex.test(String(field)) && !obj.propertyIsEnumerable(field)) {
++      return undefined;
++    }
++    return obj[field];
+   });
+ }
+--- a/spec/security.js
++++ b/spec/security.js
+@@ -21,6 +21,36 @@
+         });
+     });
+ 
++    describe('GH-1563', function() {
++        it('should not allow to access constructor after overriding via __defineGetter__', function() {
++            if (({}).__defineGetter__ == null || ({}).__lookupGetter__ == null) {
++                return this.skip(); // Browser does not support this exploit anyway
++            }
++            expectTemplate('{{__defineGetter__ "undefined" valueOf }}' +
++                '{{#with __lookupGetter__ }}' +
++                '{{__defineGetter__ "propertyIsEnumerable" (this.bind (this.bind 1)) }}' +
++                '{{constructor.name}}' +
++                '{{/with}}')
++                .withInput({})
++                .toThrow(/Missing helper: "__defineGetter__"/);
++        });
++    });
++
++    describe('GH-1595', function() {
++      it('properties, that are required to be enumerable', function() {
++        expectTemplate('{{constructor}}').withInput({}).toCompileTo('');
++        expectTemplate('{{__defineGetter__}}').withInput({}).toCompileTo('');
++        expectTemplate('{{__defineSetter__}}').withInput({}).toCompileTo('');
++        expectTemplate('{{__lookupGetter__}}').withInput({}).toCompileTo('');
++        expectTemplate('{{__proto__}}').withInput({}).toCompileTo('');
++
++        expectTemplate('{{lookup "constructor"}}').withInput({}).toCompileTo('');
++        expectTemplate('{{lookup "__defineGetter__"}}').withInput({}).toCompileTo('');
++        expectTemplate('{{lookup "__defineSetter__"}}').withInput({}).toCompileTo('');
++        expectTemplate('{{lookup "__lookupGetter__"}}').withInput({}).toCompileTo('');
++        expectTemplate('{{lookup "__proto__"}}').withInput({}).toCompileTo('');
++      });
++    });
+     describe('GH-xxxx: Prevent explicit call of helperMissing-helpers', function() {
+         if (!Handlebars.compile) {
+             return;
diff --git a/debian/patches/CVE-2021-23369.patch b/debian/patches/CVE-2021-23369.patch
new file mode 100644
index 0000000..81ca9be
--- /dev/null
+++ b/debian/patches/CVE-2021-23369.patch
@@ -0,0 +1,38 @@
+Description: fix Remote Code Execution (RCE)
+ when selecting certain compiling options to compile templates coming from an
+ untrusted source.
+Author: Nils Knappmeier <npm@knappi.org>
+Origin: upstream, https://github.com/handlebars-lang/handlebars.js/commit/b6d3de71
+ https://github.com/handlebars-lang/handlebars.js/commit/f0589701
+Bug: https://snyk.io/vuln/SNYK-JS-HANDLEBARS-1056767
+Forwarded: not-needed
+Reviewed-By: Yadd <yadd@debian.org>
+Last-Update: 2021-04-16
+
+--- a/lib/handlebars/compiler/javascript-compiler.js
++++ b/lib/handlebars/compiler/javascript-compiler.js
+@@ -25,7 +25,12 @@
+     }
+   },
+   depthedLookup: function(name) {
+-    return [this.aliasable('container.lookup'), '(depths, "', name, '")'];
++    return [
++      this.aliasable('container.lookup'),
++      '(depths, ',
++      JSON.stringify(name),
++      ')'
++    ];
+   },
+ 
+   compilerInfo: function() {
+--- a/lib/handlebars/runtime.js
++++ b/lib/handlebars/runtime.js
+@@ -78,7 +78,7 @@
+       if (!(name in obj)) {
+         throw new Exception('"' + name + '" not defined in ' + obj);
+       }
+-      return obj[name];
++      return container.lookupProperty(obj, name);
+     },
+     lookup: function(depths, name) {
+       const len = depths.length;
diff --git a/debian/patches/series b/debian/patches/series
index 7cf0804..da74c64 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,3 +2,5 @@ port-to-babel6-webpack3.patch
 skip-some-modules.patch
 use-system-jison.patch
 CVE-2019-19919.patch
+CVE-2019-20920.patch
+CVE-2021-23369.patch

Reply to: