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

Bug#994555: marked as done (bullseye-pu: package node-object-path/0.11.5-3+deb11u1)



Your message dated Sat, 09 Oct 2021 12:09:40 +0100
with message-id <81741a2f4e370c14a3bec08b7fe6e2b10c32267b.camel@adam-barratt.org.uk>
and subject line Closing p-u bugs for updates in 11.1
has caused the Debian Bug report #994555,
regarding bullseye-pu: package node-object-path/0.11.5-3+deb11u1
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.)


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

[ Reason ]
node-object-path is vulnerable to prototye pollution (CVE-2021-23434 and
CVE-2021-3805

[ Impact ]
Medium vulnerability

[ Tests ]
Test passed with these patches, including new checks

[ Risks ]
Low risk, package is not really different than the one pushed to
unstable (only doc differs).

[ 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 ]
Better checks

[ Other info ]
Note that we could upload a 0.11.8-1~deb11u1: there is no differences
except a documentation update. If you agree, I prefer this way.

Cheers,
Yadd
diff --git a/debian/changelog b/debian/changelog
index f1e6929..ce9339e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+node-object-path (0.11.5-3+deb11u1) bullseye; urgency=medium
+
+  * Team upload
+  * Fix prototype pollution (Closes: CVE-2021-23434)
+  * Fix prototype pollution (Closes: CVE-2021-3805)
+
+ -- Yadd <yadd@debian.org>  Fri, 17 Sep 2021 18:38:10 +0200
+
 node-object-path (0.11.5-3) unstable; urgency=medium
 
   * Team upload
diff --git a/debian/gbp.conf b/debian/gbp.conf
index b713356..e11bcb5 100644
--- a/debian/gbp.conf
+++ b/debian/gbp.conf
@@ -1,5 +1,6 @@
 [DEFAULT]
 pristine-tar = True
+debian-branch = bullseye
 
 [import-orig]
 filter = [ '.gitignore', '.travis.yml', '.git*' ]
diff --git a/debian/patches/CVE-2021-23434.patch b/debian/patches/CVE-2021-23434.patch
new file mode 100644
index 0000000..8d08d2e
--- /dev/null
+++ b/debian/patches/CVE-2021-23434.patch
@@ -0,0 +1,67 @@
+Description: Fix prototype pollution when path components are not strings
+Author: Mario Casciaro <mariocasciaro@gmail.com
+Origin: upstream, https://github.com/mariocasciaro/object-path/commit/7bdf4abef
+Bug: https://snyk.io/vuln/SNYK-JS-OBJECTPATH-1569453
+Forwarded: not-needed
+Reviewed-By: Yadd <yadd@debian.org>
+Last-Update: 2021-09-17
+
+--- a/index.js
++++ b/index.js
+@@ -111,6 +111,9 @@
+         return set(obj, path.split('.').map(getKey), value, doNotReplace);
+       }
+       var currentPath = path[0];
++      if (typeof currentPath !== 'string' && typeof currentPath !== 'number') {
++        currentPath = String(currentPath)
++      }
+       var currentValue = getShallowProperty(obj, currentPath);
+       if (options.includeInheritedProps && (currentPath === '__proto__' ||
+         (currentPath === 'constructor' && typeof currentValue === 'function'))) {
+--- a/test.js
++++ b/test.js
+@@ -241,12 +241,18 @@
+     objectPath.set({}, '__proto__.injected', 'this is bad')
+     expect(Object.prototype.injected).to.be.undefined
+ 
++    objectPath.set({}, [['__proto__'], 'injected'], 'this is bad')
++    expect(Object.prototype.injected).to.be.undefined
++
+     function Clazz() {}
+     Clazz.prototype.test = 'original'
+ 
+     objectPath.set(new Clazz(), '__proto__.test', 'this is bad')
+     expect(Clazz.prototype.test).to.be.equal('original')
+ 
++    objectPath.set(new Clazz(), [['__proto__'], 'test'], 'this is bad')
++    expect(Clazz.prototype.test).to.be.equal('original')
++
+     objectPath.set(new Clazz(), 'constructor.prototype.test', 'this is bad')
+     expect(Clazz.prototype.test).to.be.equal('original')
+   })
+@@ -256,6 +262,11 @@
+       .to.throw('For security reasons')
+     expect(Object.prototype.injected).to.be.undefined
+ 
++    expect(function() {
++      objectPath.withInheritedProps.set({}, [['__proto__'], 'injected'], 'this is bad')
++      expect(Object.prototype.injected).to.be.undefined
++    }).to.throw('For security reasons')
++
+     function Clazz() {}
+     Clazz.prototype.test = 'original'
+ 
+@@ -267,8 +278,11 @@
+       .to.throw('For security reasons')
+     expect(Clazz.prototype.test).to.be.equal('original')
+ 
+-    const obj = {}
+-    expect(function() {objectPath.withInheritedProps.set(obj, 'constructor.prototype.injected', 'this is OK')})
++    expect(function() {objectPath.withInheritedProps.set({}, 'constructor.prototype.injected', 'this is OK')})
++      .to.throw('For security reasons')
++    expect(Object.prototype.injected).to.be.undefined
++
++    expect(function() {objectPath.withInheritedProps.set({}, [['constructor'], 'prototype', 'injected'], 'this is bad')})
+       .to.throw('For security reasons')
+     expect(Object.prototype.injected).to.be.undefined
+   })
diff --git a/debian/patches/CVE-2021-3805.patch b/debian/patches/CVE-2021-3805.patch
new file mode 100644
index 0000000..daa56ff
--- /dev/null
+++ b/debian/patches/CVE-2021-3805.patch
@@ -0,0 +1,837 @@
+Description: Fix prototype pollution vulnerability
+Author: Mario Casciaro <mariocasciaro@gmail.com>
+Origin: upstream, https://github.com/mariocasciaro/object-path/commit/4f0903fd7
+Bug: https://huntr.dev/bounties/571e3baf-7c46-46e3-9003-ba7e4e623053
+Forwarded: not-needed
+Reviewed-By: Yadd <yadd@debian.org>
+Last-Update: 2021-09-17
+
+--- a/README.md
++++ b/README.md
+@@ -172,6 +172,8 @@
+ objectPath.set(obj, 'notOwn.prop', 'b');
+ ```
+ 
++**NOTE**: For security reasons `object-path` will throw an exception when trying to access an object's magic properties (e.g. `__proto__`, `constructor`) when in "inherited props" mode.
++
+ ### Immutability
+ 
+ If you are looking for an *immutable* alternative of this library, you can take a look at: [object-path-immutable](https://github.com/mariocasciaro/object-path-immutable)
+--- a/index.js
++++ b/index.js
+@@ -1,87 +1,88 @@
+-(function (root, factory){
+-  'use strict';
++(function (root, factory) {
++  'use strict'
+ 
+   /*istanbul ignore next:cant test*/
+   if (typeof module === 'object' && typeof module.exports === 'object') {
+-    module.exports = factory();
++    module.exports = factory()
+   } else if (typeof define === 'function' && define.amd) {
+     // AMD. Register as an anonymous module.
+-    define([], factory);
++    define([], factory)
+   } else {
+     // Browser globals
+-    root.objectPath = factory();
++    root.objectPath = factory()
+   }
+-})(this, function(){
+-  'use strict';
++})(this, function () {
++  'use strict'
+ 
+-  var toStr = Object.prototype.toString;
+-  function hasOwnProperty(obj, prop) {
+-    if(obj == null) {
++  var toStr = Object.prototype.toString
++
++  function hasOwnProperty (obj, prop) {
++    if (obj == null) {
+       return false
+     }
+     //to handle objects with null prototypes (too edge case?)
+     return Object.prototype.hasOwnProperty.call(obj, prop)
+   }
+ 
+-  function isEmpty(value){
++  function isEmpty (value) {
+     if (!value) {
+-      return true;
++      return true
+     }
+     if (isArray(value) && value.length === 0) {
+-        return true;
++      return true
+     } else if (typeof value !== 'string') {
+-        for (var i in value) {
+-            if (hasOwnProperty(value, i)) {
+-                return false;
+-            }
++      for (var i in value) {
++        if (hasOwnProperty(value, i)) {
++          return false
+         }
+-        return true;
++      }
++      return true
+     }
+-    return false;
++    return false
+   }
+ 
+-  function toString(type){
+-    return toStr.call(type);
++  function toString (type) {
++    return toStr.call(type)
+   }
+ 
+-  function isObject(obj){
+-    return typeof obj === 'object' && toString(obj) === "[object Object]";
++  function isObject (obj) {
++    return typeof obj === 'object' && toString(obj) === '[object Object]'
+   }
+ 
+-  var isArray = Array.isArray || function(obj){
++  var isArray = Array.isArray || function (obj) {
+     /*istanbul ignore next:cant test*/
+-    return toStr.call(obj) === '[object Array]';
++    return toStr.call(obj) === '[object Array]'
+   }
+ 
+-  function isBoolean(obj){
+-    return typeof obj === 'boolean' || toString(obj) === '[object Boolean]';
++  function isBoolean (obj) {
++    return typeof obj === 'boolean' || toString(obj) === '[object Boolean]'
+   }
+ 
+-  function getKey(key){
+-    var intKey = parseInt(key);
++  function getKey (key) {
++    var intKey = parseInt(key)
+     if (intKey.toString() === key) {
+-      return intKey;
++      return intKey
+     }
+-    return key;
++    return key
+   }
+ 
+-  function factory(options) {
++  function factory (options) {
+     options = options || {}
+ 
+-    var objectPath = function(obj) {
+-      return Object.keys(objectPath).reduce(function(proxy, prop) {
+-        if(prop === 'create') {
+-          return proxy;
++    var objectPath = function (obj) {
++      return Object.keys(objectPath).reduce(function (proxy, prop) {
++        if (prop === 'create') {
++          return proxy
+         }
+ 
+         /*istanbul ignore else*/
+         if (typeof objectPath[prop] === 'function') {
+-          proxy[prop] = objectPath[prop].bind(objectPath, obj);
++          proxy[prop] = objectPath[prop].bind(objectPath, obj)
+         }
+ 
+-        return proxy;
+-      }, {});
+-    };
++        return proxy
++      }, {})
++    }
+ 
+     var hasShallowProperty
+     if (options.includeInheritedProps) {
+@@ -94,213 +95,226 @@
+       }
+     }
+ 
+-    function getShallowProperty(obj, prop) {
++    function getShallowProperty (obj, prop) {
+       if (hasShallowProperty(obj, prop)) {
+-        return obj[prop];
++        return obj[prop]
++      }
++    }
++
++    var getShallowPropertySafely
++    if (options.includeInheritedProps) {
++      getShallowPropertySafely = function (obj, currentPath) {
++        if (typeof currentPath !== 'string' && typeof currentPath !== 'number') {
++          currentPath = String(currentPath)
++        }
++        var currentValue = getShallowProperty(obj, currentPath)
++        if (currentPath === '__proto__' || currentPath === 'prototype' ||
++          (currentPath === 'constructor' && typeof currentValue === 'function')) {
++          throw new Error('For security reasons, object\'s magic properties cannot be set')
++        }
++        return currentValue
++      }
++    } else {
++      getShallowPropertySafely = function (obj, currentPath) {
++        return getShallowProperty(obj, currentPath)
+       }
+     }
+ 
+-    function set(obj, path, value, doNotReplace){
++    function set (obj, path, value, doNotReplace) {
+       if (typeof path === 'number') {
+-        path = [path];
++        path = [path]
+       }
+       if (!path || path.length === 0) {
+-        return obj;
++        return obj
+       }
+       if (typeof path === 'string') {
+-        return set(obj, path.split('.').map(getKey), value, doNotReplace);
+-      }
+-      var currentPath = path[0];
+-      if (typeof currentPath !== 'string' && typeof currentPath !== 'number') {
+-        currentPath = String(currentPath)
+-      }
+-      var currentValue = getShallowProperty(obj, currentPath);
+-      if (options.includeInheritedProps && (currentPath === '__proto__' ||
+-        (currentPath === 'constructor' && typeof currentValue === 'function'))) {
+-        throw new Error('For security reasons, object\'s magic properties cannot be set')
++        return set(obj, path.split('.').map(getKey), value, doNotReplace)
+       }
++      var currentPath = path[0]
++      var currentValue = getShallowPropertySafely(obj, currentPath)
+       if (path.length === 1) {
+         if (currentValue === void 0 || !doNotReplace) {
+-          obj[currentPath] = value;
++          obj[currentPath] = value
+         }
+-        return currentValue;
++        return currentValue
+       }
+ 
+       if (currentValue === void 0) {
+         //check if we assume an array
+-        if(typeof path[1] === 'number') {
+-          obj[currentPath] = [];
++        if (typeof path[1] === 'number') {
++          obj[currentPath] = []
+         } else {
+-          obj[currentPath] = {};
++          obj[currentPath] = {}
+         }
+       }
+ 
+-      return set(obj[currentPath], path.slice(1), value, doNotReplace);
++      return set(obj[currentPath], path.slice(1), value, doNotReplace)
+     }
+ 
+     objectPath.has = function (obj, path) {
+       if (typeof path === 'number') {
+-        path = [path];
++        path = [path]
+       } else if (typeof path === 'string') {
+-        path = path.split('.');
++        path = path.split('.')
+       }
+ 
+       if (!path || path.length === 0) {
+-        return !!obj;
++        return !!obj
+       }
+ 
+       for (var i = 0; i < path.length; i++) {
+-        var j = getKey(path[i]);
++        var j = getKey(path[i])
+ 
+-        if((typeof j === 'number' && isArray(obj) && j < obj.length) ||
++        if ((typeof j === 'number' && isArray(obj) && j < obj.length) ||
+           (options.includeInheritedProps ? (j in Object(obj)) : hasOwnProperty(obj, j))) {
+-          obj = obj[j];
++          obj = obj[j]
+         } else {
+-          return false;
++          return false
+         }
+       }
+ 
+-      return true;
+-    };
++      return true
++    }
+ 
+-    objectPath.ensureExists = function (obj, path, value){
+-      return set(obj, path, value, true);
+-    };
++    objectPath.ensureExists = function (obj, path, value) {
++      return set(obj, path, value, true)
++    }
+ 
+-    objectPath.set = function (obj, path, value, doNotReplace){
+-      return set(obj, path, value, doNotReplace);
+-    };
++    objectPath.set = function (obj, path, value, doNotReplace) {
++      return set(obj, path, value, doNotReplace)
++    }
+ 
+-    objectPath.insert = function (obj, path, value, at){
+-      var arr = objectPath.get(obj, path);
+-      at = ~~at;
++    objectPath.insert = function (obj, path, value, at) {
++      var arr = objectPath.get(obj, path)
++      at = ~~at
+       if (!isArray(arr)) {
+-        arr = [];
+-        objectPath.set(obj, path, arr);
++        arr = []
++        objectPath.set(obj, path, arr)
+       }
+-      arr.splice(at, 0, value);
+-    };
++      arr.splice(at, 0, value)
++    }
+ 
+-    objectPath.empty = function(obj, path) {
++    objectPath.empty = function (obj, path) {
+       if (isEmpty(path)) {
+-        return void 0;
++        return void 0
+       }
+       if (obj == null) {
+-        return void 0;
++        return void 0
+       }
+ 
+-      var value, i;
++      var value, i
+       if (!(value = objectPath.get(obj, path))) {
+-        return void 0;
++        return void 0
+       }
+ 
+       if (typeof value === 'string') {
+-        return objectPath.set(obj, path, '');
++        return objectPath.set(obj, path, '')
+       } else if (isBoolean(value)) {
+-        return objectPath.set(obj, path, false);
++        return objectPath.set(obj, path, false)
+       } else if (typeof value === 'number') {
+-        return objectPath.set(obj, path, 0);
++        return objectPath.set(obj, path, 0)
+       } else if (isArray(value)) {
+-        value.length = 0;
++        value.length = 0
+       } else if (isObject(value)) {
+         for (i in value) {
+           if (hasShallowProperty(value, i)) {
+-            delete value[i];
++            delete value[i]
+           }
+         }
+       } else {
+-        return objectPath.set(obj, path, null);
++        return objectPath.set(obj, path, null)
+       }
+-    };
++    }
+ 
+-    objectPath.push = function (obj, path /*, values */){
+-      var arr = objectPath.get(obj, path);
++    objectPath.push = function (obj, path /*, values */) {
++      var arr = objectPath.get(obj, path)
+       if (!isArray(arr)) {
+-        arr = [];
+-        objectPath.set(obj, path, arr);
++        arr = []
++        objectPath.set(obj, path, arr)
+       }
+ 
+-      arr.push.apply(arr, Array.prototype.slice.call(arguments, 2));
+-    };
++      arr.push.apply(arr, Array.prototype.slice.call(arguments, 2))
++    }
+ 
+     objectPath.coalesce = function (obj, paths, defaultValue) {
+-      var value;
++      var value
+ 
+       for (var i = 0, len = paths.length; i < len; i++) {
+         if ((value = objectPath.get(obj, paths[i])) !== void 0) {
+-          return value;
++          return value
+         }
+       }
+ 
+-      return defaultValue;
+-    };
++      return defaultValue
++    }
+ 
+-    objectPath.get = function (obj, path, defaultValue){
++    objectPath.get = function (obj, path, defaultValue) {
+       if (typeof path === 'number') {
+-        path = [path];
++        path = [path]
+       }
+       if (!path || path.length === 0) {
+-        return obj;
++        return obj
+       }
+       if (obj == null) {
+-        return defaultValue;
++        return defaultValue
+       }
+       if (typeof path === 'string') {
+-        return objectPath.get(obj, path.split('.'), defaultValue);
++        return objectPath.get(obj, path.split('.'), defaultValue)
+       }
+ 
+-      var currentPath = getKey(path[0]);
+-      var nextObj = getShallowProperty(obj, currentPath)
++      var currentPath = getKey(path[0])
++      var nextObj = getShallowPropertySafely(obj, currentPath)
+       if (nextObj === void 0) {
+-        return defaultValue;
++        return defaultValue
+       }
+ 
+       if (path.length === 1) {
+-        return nextObj;
++        return nextObj
+       }
+ 
+-      return objectPath.get(obj[currentPath], path.slice(1), defaultValue);
+-    };
++      return objectPath.get(obj[currentPath], path.slice(1), defaultValue)
++    }
+ 
+-    objectPath.del = function del(obj, path) {
++    objectPath.del = function del (obj, path) {
+       if (typeof path === 'number') {
+-        path = [path];
++        path = [path]
+       }
+ 
+       if (obj == null) {
+-        return obj;
++        return obj
+       }
+ 
+       if (isEmpty(path)) {
+-        return obj;
++        return obj
+       }
+-      if(typeof path === 'string') {
+-        return objectPath.del(obj, path.split('.'));
++      if (typeof path === 'string') {
++        return objectPath.del(obj, path.split('.'))
+       }
+ 
+-      var currentPath = getKey(path[0]);
++      var currentPath = getKey(path[0])
++      getShallowPropertySafely(obj, currentPath)
+       if (!hasShallowProperty(obj, currentPath)) {
+-        return obj;
++        return obj
+       }
+ 
+-      if(path.length === 1) {
++      if (path.length === 1) {
+         if (isArray(obj)) {
+-          obj.splice(currentPath, 1);
++          obj.splice(currentPath, 1)
+         } else {
+-          delete obj[currentPath];
++          delete obj[currentPath]
+         }
+       } else {
+-        return objectPath.del(obj[currentPath], path.slice(1));
++        return objectPath.del(obj[currentPath], path.slice(1))
+       }
+ 
+-      return obj;
++      return obj
+     }
+ 
+-    return objectPath;
++    return objectPath
+   }
+ 
+-  var mod = factory();
+-  mod.create = factory;
++  var mod = factory()
++  mod.create = factory
+   mod.withInheritedProps = factory({includeInheritedProps: true})
+-  return mod;
+-});
++  return mod
++})
+--- a/test.js
++++ b/test.js
+@@ -133,6 +133,43 @@
+     expect(objectPath.get(extended, 'enabled')).to.be.equal(true)
+     expect(objectPath.get(extended, 'one')).to.be.equal(undefined)
+   })
++
++  it('[security] should not get magic properties in default mode', function () {
++    expect(objectPath.get({}, '__proto__')).to.be.undefined
++    expect(objectPath.get({}, [['__proto__']])).to.be.undefined
++
++    function Clazz() {}
++    Clazz.prototype.test = []
++
++    expect(objectPath.get(new Clazz(), '__proto__')).to.be.undefined
++    expect(objectPath.get(new Clazz(), [['__proto__']])).to.be.undefined
++    expect(objectPath.get(new Clazz(), ['constructor', 'prototype'])).to.be.undefined
++  })
++
++  it('[security] should not get magic properties in inheritedProps mode', function () {
++    expect(function() {
++      objectPath.withInheritedProps.get({}, '__proto__')
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.get({}, [['__proto__']])
++    }).to.throw('For security reasons')
++
++    function Clazz() {}
++    Clazz.prototype.test = 'original'
++
++    expect(function() {
++      objectPath.withInheritedProps.get(new Clazz(), '__proto__')
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.get(new Clazz(), [['__proto__']])
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.get(new Clazz(), ['constructor', 'prototype'])
++    }).to.throw('For security reasons')
++  })
+ })
+ 
+ 
+@@ -244,9 +281,15 @@
+     objectPath.set({}, [['__proto__'], 'injected'], 'this is bad')
+     expect(Object.prototype.injected).to.be.undefined
+ 
++    objectPath.set({}, ['__proto__'], {})
++    expect(Object.prototype.toString).to.be.a('function')
++
+     function Clazz() {}
+     Clazz.prototype.test = 'original'
+ 
++    objectPath.set({}, ['__proto__'], {test: 'this is bad'})
++    expect(Clazz.prototype.test).to.be.equal('original')
++
+     objectPath.set(new Clazz(), '__proto__.test', 'this is bad')
+     expect(Clazz.prototype.test).to.be.equal('original')
+ 
+@@ -258,9 +301,10 @@
+   })
+ 
+   it('[security] should throw an exception if trying to set magic properties in inheritedProps mode', function () {
+-    expect(function() {objectPath.withInheritedProps.set({}, '__proto__.injected', 'this is bad')})
+-      .to.throw('For security reasons')
+-    expect(Object.prototype.injected).to.be.undefined
++    expect(function() {
++      objectPath.withInheritedProps.set({}, '__proto__.injected', 'this is bad')
++      expect(Object.prototype.injected).to.be.undefined
++    }).to.throw('For security reasons')
+ 
+     expect(function() {
+       objectPath.withInheritedProps.set({}, [['__proto__'], 'injected'], 'this is bad')
+@@ -270,21 +314,25 @@
+     function Clazz() {}
+     Clazz.prototype.test = 'original'
+ 
+-    expect(function() {objectPath.withInheritedProps.set(new Clazz(), '__proto__.test', 'this is bad')})
+-      .to.throw('For security reasons')
+-    expect(Clazz.prototype.test).to.be.equal('original')
++    expect(function() {
++      objectPath.withInheritedProps.set(new Clazz(), '__proto__.test', 'this is bad')
++      expect(Clazz.prototype.test).to.be.equal('original')
++    }).to.throw('For security reasons')
+ 
+-    expect(function() {objectPath.withInheritedProps.set(new Clazz(), 'constructor.prototype.test', 'this is bad')})
+-      .to.throw('For security reasons')
+-    expect(Clazz.prototype.test).to.be.equal('original')
++    expect(function() {
++      objectPath.withInheritedProps.set(new Clazz(), 'constructor.prototype.test', 'this is bad')
++      expect(Clazz.prototype.test).to.be.equal('original')
++    }).to.throw('For security reasons')
+ 
+-    expect(function() {objectPath.withInheritedProps.set({}, 'constructor.prototype.injected', 'this is OK')})
+-      .to.throw('For security reasons')
+-    expect(Object.prototype.injected).to.be.undefined
++    expect(function() {
++      objectPath.withInheritedProps.set({}, 'constructor.prototype.injected', 'this is OK')
++      expect(Object.prototype.injected).to.be.undefined
++    }).to.throw('For security reasons')
+ 
+-    expect(function() {objectPath.withInheritedProps.set({}, [['constructor'], 'prototype', 'injected'], 'this is bad')})
+-      .to.throw('For security reasons')
+-    expect(Object.prototype.injected).to.be.undefined
++    expect(function() {
++      objectPath.withInheritedProps.set({}, [['constructor'], 'prototype', 'injected'], 'this is bad')
++      expect(Object.prototype.injected).to.be.undefined
++    }).to.throw('For security reasons')
+   })
+ })
+ 
+@@ -328,6 +376,39 @@
+     expect(obj).to.have.nested.property('b.e.0.0', 'l')
+   })
+ 
++  it('[security] should not push within prototype properties in default mode', function () {
++    function Clazz() {}
++    Clazz.prototype.test = []
++
++    objectPath.push(new Clazz(), '__proto__.test', 'pushed')
++    expect(Clazz.prototype.test).to.be.deep.equal([])
++
++    objectPath.push(new Clazz(), [['__proto__'], 'test'], 'pushed')
++    expect(Clazz.prototype.test).to.be.deep.equal([])
++
++    objectPath.push(new Clazz(), 'constructor.prototype.test', 'pushed')
++    expect(Clazz.prototype.test).to.be.deep.equal([])
++  })
++
++  it('[security] should not push within prototype properties in inheritedProps mode', function () {
++    function Clazz() {}
++    Clazz.prototype.test = []
++
++    expect(function() {
++      objectPath.withInheritedProps.push(new Clazz(), '__proto__.test', 'pushed')
++      expect(Clazz.prototype.test).to.be.deep.equal([])
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.push(new Clazz(), [['__proto__'], 'test'], 'pushed')
++      expect(Clazz.prototype.test).to.be.deep.equal([])
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.push(new Clazz(), 'constructor.prototype.test', 'pushed')
++      expect(Clazz.prototype.test).to.be.deep.equal([])
++    }).to.throw('For security reasons')
++  })
+ })
+ 
+ 
+@@ -361,6 +442,67 @@
+     expect(any[1]).to.be.an('object')
+     expect(any[1][1]).to.be.an('object')
+   })
++
++  it('[security] should not set magic properties in default mode', function () {
++    objectPath.ensureExists({}, '__proto__.injected', 'this is bad')
++    expect(Object.prototype.injected).to.be.undefined
++
++    objectPath.ensureExists({}, [['__proto__'], 'injected'], 'this is bad')
++    expect(Object.prototype.injected).to.be.undefined
++
++    objectPath.ensureExists({}, ['__proto__'], {})
++    expect(Object.prototype.toString).to.be.a('function')
++
++    function Clazz() {}
++    Clazz.prototype.test = 'original'
++
++    objectPath.ensureExists({}, ['__proto__'], {test: 'this is bad'})
++    expect(Clazz.prototype.test).to.be.equal('original')
++
++    objectPath.ensureExists(new Clazz(), '__proto__.test', 'this is bad')
++    expect(Clazz.prototype.test).to.be.equal('original')
++
++    objectPath.ensureExists(new Clazz(), [['__proto__'], 'test'], 'this is bad')
++    expect(Clazz.prototype.test).to.be.equal('original')
++
++    objectPath.ensureExists(new Clazz(), 'constructor.prototype.test', 'this is bad')
++    expect(Clazz.prototype.test).to.be.equal('original')
++  })
++
++  it('[security] should throw an exception if trying to set magic properties in inheritedProps mode', function () {
++    expect(function() {objectPath.withInheritedProps.ensureExists({}, '__proto__.injected', 'this is bad')})
++      .to.throw('For security reasons')
++    expect(Object.prototype.injected).to.be.undefined
++
++    expect(function() {
++      objectPath.withInheritedProps.ensureExists({}, [['__proto__'], 'injected'], 'this is bad')
++      expect(Object.prototype.injected).to.be.undefined
++    }).to.throw('For security reasons')
++
++    function Clazz() {}
++    Clazz.prototype.test = 'original'
++
++    expect(function() {
++      objectPath.withInheritedProps.ensureExists(new Clazz(), '__proto__.test', 'this is bad')
++      expect(Clazz.prototype.test).to.be.equal('original')
++    }).to.throw('For security reasons')
++
++
++    expect(function() {
++      objectPath.withInheritedProps.ensureExists(new Clazz(), 'constructor.prototype.test', 'this is bad')
++      expect(Clazz.prototype.test).to.be.equal('original')
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.ensureExists({}, 'constructor.prototype.injected', 'this is OK')
++      expect(Object.prototype.injected).to.be.undefined
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.ensureExists({}, [['constructor'], 'prototype', 'injected'], 'this is bad')
++      expect(Object.prototype.injected).to.be.undefined
++    }).to.throw('For security reasons')
++  })
+ })
+ 
+ describe('coalesce', function () {
+@@ -512,6 +654,40 @@
+     expect(obj.instance.arr).to.be.an('array')
+     expect(obj['function']).to.equal(null)
+   })
++
++  it('[security] should not empty prototype properties in default mode', function () {
++    function Clazz() {}
++    Clazz.prototype.test = 'original'
++
++    objectPath.empty(new Clazz(), '__proto__')
++    expect(Clazz.prototype.test).to.be.equal('original')
++
++    objectPath.empty(new Clazz(), [['__proto__']])
++    expect(Clazz.prototype.test).to.be.equal('original')
++
++    objectPath.empty(new Clazz(), 'constructor.prototype')
++    expect(Clazz.prototype.test).to.be.equal('original')
++  })
++
++  it('[security] should throw an exception if trying to delete prototype properties in inheritedProps mode', function () {
++    function Clazz() {}
++    Clazz.prototype.test = 'original'
++
++    expect(function() {
++      objectPath.withInheritedProps.empty(new Clazz(), '__proto__')
++      expect(Clazz.prototype.test).to.be.equal('original')
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.empty(new Clazz(), 'constructor.prototype')
++      expect(Clazz.prototype.test).to.be.equal('original')
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.empty({}, [['constructor'], 'prototype'])
++      expect(Clazz.prototype.test).to.be.equal('original')
++    }).to.throw('For security reasons')
++  })
+ })
+ 
+ describe('del', function () {
+@@ -588,6 +764,56 @@
+     expect(obj.b.d).to.have.length(0)
+     expect(obj.b.d).to.be.deep.equal([])
+   })
++
++  it('[security] should not delete prototype properties in default mode', function () {
++    objectPath.del({}, '__proto__.valueOf')
++    expect(Object.prototype.valueOf).to.be.a('function')
++
++    objectPath.del({}, [['__proto__'], 'valueOf'])
++    expect(Object.prototype.valueOf).to.be.a('function')
++
++    function Clazz() {}
++    Clazz.prototype.test = 'original'
++
++    objectPath.del(new Clazz(), '__proto__.test')
++    expect(Clazz.prototype.test).to.be.equal('original')
++
++    objectPath.del(new Clazz(), [['__proto__'], 'test'])
++    expect(Clazz.prototype.test).to.be.equal('original')
++
++    objectPath.del(new Clazz(), 'constructor.prototype.test')
++    expect(Clazz.prototype.test).to.be.equal('original')
++  })
++
++  it('[security] should throw an exception if trying to delete prototype properties in inheritedProps mode', function () {
++    expect(function() {
++      objectPath.withInheritedProps.del({}, '__proto__.valueOf')
++      expect(Object.prototype.valueOf).to.be.a('function')
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.del({}, [['__proto__'], 'valueOf'])
++      expect(Object.prototype.valueOf).to.be.a('function')
++    }).to.throw('For security reasons')
++
++    function Clazz() {}
++    Clazz.prototype.test = 'original'
++
++    expect(function() {
++      objectPath.withInheritedProps.del(new Clazz(), '__proto__.test')
++      expect(Clazz.prototype.test).to.be.equal('original')
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.del(new Clazz(), 'constructor.prototype.test', 'this is bad')
++      expect(Clazz.prototype.test).to.be.equal('original')
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.del({}, [['constructor'], 'prototype', 'test'])
++      expect(Clazz.prototype.test).to.be.equal('original')
++    }).to.throw('For security reasons')
++  })
+ })
+ 
+ describe('insert', function () {
+@@ -630,6 +856,45 @@
+       'asdf'
+     ])
+   })
++
++  it('[security] should not insert within prototype properties in default mode', function () {
++    function Clazz() {}
++    Clazz.prototype.test = []
++
++    objectPath.insert(new Clazz(), '__proto__.test', 'inserted', 0)
++    expect(Clazz.prototype.test).to.be.deep.equal([])
++
++    objectPath.insert(new Clazz(), [['__proto__'], 'test'], 'inserted', 0)
++    expect(Clazz.prototype.test).to.be.deep.equal([])
++
++    objectPath.insert(new Clazz(), 'constructor.prototype.test', 'inserted', 0)
++    expect(Clazz.prototype.test).to.be.deep.equal([])
++  })
++
++  it('[security] should not insert within prototype properties in inheritedProps mode', function () {
++    function Clazz() {}
++    Clazz.prototype.test = []
++
++    expect(function() {
++      objectPath.withInheritedProps.insert(new Clazz(), '__proto__.test', 'inserted', 0)
++      expect(Clazz.prototype.test).to.be.deep.equal([])
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.insert(new Clazz(), [['__proto__'], 'test'], 'inserted', 0)
++      expect(Clazz.prototype.test).to.be.deep.equal([])
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.insert(new Clazz(), 'constructor.prototype.test', 'inserted', 0)
++      expect(Clazz.prototype.test).to.be.deep.equal([])
++    }).to.throw('For security reasons')
++
++    expect(function() {
++      objectPath.withInheritedProps.insert(new Clazz().constructor, 'prototype.test', 'inserted', 0)
++      expect(Clazz.prototype.test).to.be.deep.equal([])
++    }).to.throw('For security reasons')
++  })
+ })
+ 
+ describe('has', function () {
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..7b1f359
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,2 @@
+CVE-2021-23434.patch
+CVE-2021-3805.patch
diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml
index 33c3a64..6fd902a 100644
--- a/debian/salsa-ci.yml
+++ b/debian/salsa-ci.yml
@@ -1,4 +1,7 @@
 ---
+variables:
+  RELEASE: 'bullseye'
+
 include:
   - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
   - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml

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

Hi,

The updates relating to these bugs were included in this morning's 11.1
point release for bullseye.

Regards,

Adam

--- End Message ---

Reply to: