VYPR
High severityNVD Advisory· Published Dec 25, 2022· Updated Aug 3, 2024

cronvel tree-kit prototype pollution

CVE-2021-4278

Description

cronvel tree-kit up to 0.6.x is vulnerable to prototype pollution via its .extend() method, leading to potential property injection in Node.js applications.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

cronvel tree-kit up to 0.6.x is vulnerable to prototype pollution via its .extend() method, leading to potential property injection in Node.js applications.

Vulnerability

Overview

CVE-2021-4278 is a prototype pollution vulnerability in the tree-kit library for Node.js, affecting versions up to and including 0.6.x [1][2]. The vulnerability exists in an unknown part of the library, but the library's primary feature is the .extend() method, which can recursively merge objects [1]. Improper handling of object properties during this process allows an attacker to modify the built-in Object.prototype, leading to prototype pollution [2].

Exploitation and

Attack Vector

Exploitation of the vulnerability does not require authentication beyond what the application context provides [2]. The attack can be delivered by supplying a crafted object to the .extend() function, which then pollutes the prototype chain [1]. Since the library is designed for use in Node.js applications, the attack surface includes any application that processes user-controlled input through tree-kit's extend operation [1]. The specific vector is likely a nested object with a __proto__ or constructor.prototype property that triggers the pollution [2].

Impact and

Consequences

Successful exploitation allows an attacker to inject properties into Object.prototype, which can affect all objects in the application at runtime [2]. This can lead to property injection that may enable further attacks such as arbitrary code execution, denial of service, or bypass of security checks, depending on how the application uses the polluted properties [2].

Mitigation and

Remediation

The vulnerability has been addressed in tree-kit version 0.7.0 with the commit a63f559c50d70e8cb2eaae670dec25d1dbc4afcd [3][4]. Users are strongly advised to upgrade to v0.7.0 or later to mitigate the risk [2]. No workarounds have been publicly detailed for earlier versions [1][2].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
tree-kitnpm
< 0.7.00.7.0

Affected products

2

Patches

1
a63f559c50d7

BREAKING CHANGE -- .path()/.dotPath(): drop the function's subtree support, fix prototype pollution

https://github.com/cronvel/tree-kitCédric RonvelMar 2, 2021via ghsa
4 files changed · +344 20
  • browser/tree-kit.js+336 18 modified
    @@ -2,7 +2,7 @@
     /*
     	Tree Kit
     
    -	Copyright (c) 2014 - 2019 Cédric Ronvel
    +	Copyright (c) 2014 - 2021 Cédric Ronvel
     
     	The MIT License (MIT)
     
    @@ -31,19 +31,22 @@
     
     // Browser only get the essential of tree-kit, not the unfinished parts of it
     
    -var tree = {} ;
    +const tree = {} ;
     module.exports = tree ;
     
     
    +
     tree.extend = require( './extend.js' ) ;
     tree.clone = require( './clone.js' ) ;
     tree.path = require( './path.js' ) ;
    +tree.dotPath = require( './dotPath.js' ) ;
    +
     
    -},{"./clone.js":2,"./extend.js":3,"./path.js":4}],2:[function(require,module,exports){
    +},{"./clone.js":2,"./dotPath.js":3,"./extend.js":4,"./path.js":5}],2:[function(require,module,exports){
     /*
     	Tree Kit
     
    -	Copyright (c) 2014 - 2019 Cédric Ronvel
    +	Copyright (c) 2014 - 2021 Cédric Ronvel
     
     	The MIT License (MIT)
     
    @@ -152,7 +155,312 @@ clone.opaque.set( Date.prototype , src => new Date( src ) ) ;
     /*
     	Tree Kit
     
    -	Copyright (c) 2014 - 2019 Cédric Ronvel
    +	Copyright (c) 2014 - 2021 Cédric Ronvel
    +
    +	The MIT License (MIT)
    +
    +	Permission is hereby granted, free of charge, to any person obtaining a copy
    +	of this software and associated documentation files (the "Software"), to deal
    +	in the Software without restriction, including without limitation the rights
    +	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    +	copies of the Software, and to permit persons to whom the Software is
    +	furnished to do so, subject to the following conditions:
    +
    +	The above copyright notice and this permission notice shall be included in all
    +	copies or substantial portions of the Software.
    +
    +	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    +	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    +	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    +	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    +	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    +	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    +	SOFTWARE.
    +*/
    +
    +"use strict" ;
    +
    +
    +
    +const dotPath = {} ;
    +module.exports = dotPath ;
    +
    +
    +
    +const EMPTY_PATH = [] ;
    +const PROTO_POLLUTION_MESSAGE = 'This would pollute prototype' ;
    +
    +
    +
    +function toPathArray( path ) {
    +	if ( Array.isArray( path ) ) { return path ; }
    +	else if ( ! path ) { return EMPTY_PATH ; }
    +	else if ( typeof path === 'string' ) { return path.split( '.' ) ; }
    +
    +	throw new TypeError( '[tree.dotPath]: the path argument should be a string or an array' ) ;
    +}
    +
    +
    +
    +// Walk the tree using the path array.
    +function walk( object , pathArray , maxOffset = 0 ) {
    +	var i , iMax , key ,
    +		pointer = object ;
    +
    +	for ( i = 0 , iMax = pathArray.length + maxOffset ; i < iMax ; i ++ ) {
    +		key = pathArray[ i ] ;
    +
    +		if ( key === '__proto__' || typeof pointer === 'function' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +		if ( ! pointer || typeof pointer !== 'object' ) { return undefined ; }
    +
    +		pointer = pointer[ key ] ;
    +	}
    +
    +	return pointer ;
    +}
    +
    +
    +
    +// Walk the tree, create missing element: pave the path up to before the last part of the path.
    +// Return that before-the-last element.
    +// Object MUST be an object! no check are performed for the first step!
    +function pave( object , pathArray ) {
    +	var i , iMax , key ,
    +		pointer = object ;
    +
    +	for ( i = 0 , iMax = pathArray.length - 1 ; i < iMax ; i ++ ) {
    +		key = pathArray[ i ] ;
    +
    +		if ( key === '__proto__' || typeof pointer[ key ] === 'function' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +		if ( ! pointer[ key ] || typeof pointer[ key ] !== 'object' ) { pointer[ key ] = {} ; }
    +
    +		pointer = pointer[ key ] ;
    +	}
    +
    +	return pointer ;
    +}
    +
    +
    +
    +dotPath.get = ( object , path ) => walk( object , toPathArray( path ) ) ;
    +
    +
    +
    +dotPath.set = ( object , path , value ) => {
    +	if ( ! object || typeof object !== 'object' ) {
    +		// Throw?
    +		return undefined ;
    +	}
    +
    +	var pathArray = toPathArray( path ) ,
    +		key = pathArray[ pathArray.length - 1 ] ;
    +
    +	if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +
    +	var pointer = pave( object , pathArray ) ;
    +
    +	pointer[ key ] = value ;
    +
    +	return value ;
    +} ;
    +
    +
    +
    +dotPath.define = ( object , path , value ) => {
    +	if ( ! object || typeof object !== 'object' ) {
    +		// Throw?
    +		return undefined ;
    +	}
    +
    +	var pathArray = toPathArray( path ) ,
    +		key = pathArray[ pathArray.length - 1 ] ;
    +
    +	if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +
    +	var pointer = pave( object , pathArray ) ;
    +
    +	if ( ! ( key in pointer ) ) { pointer[ key ] = value ; }
    +
    +	return value ;
    +} ;
    +
    +
    +
    +dotPath.inc = ( object , path , value ) => {
    +	if ( ! object || typeof object !== 'object' ) {
    +		// Throw?
    +		return undefined ;
    +	}
    +
    +	var pathArray = toPathArray( path ) ,
    +		key = pathArray[ pathArray.length - 1 ] ;
    +
    +	if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +
    +	var pointer = pave( object , pathArray ) ;
    +
    +	if ( typeof pointer[ key ] === 'number' ) { pointer[ key ] ++ ; }
    +	else if ( ! pointer[ key ] || typeof pointer[ key ] !== 'object' ) { pointer[ key ] = 1 ; }
    +
    +	return value ;
    +} ;
    +
    +
    +
    +dotPath.dec = ( object , path , value ) => {
    +	if ( ! object || typeof object !== 'object' ) {
    +		// Throw?
    +		return undefined ;
    +	}
    +
    +	var pathArray = toPathArray( path ) ,
    +		key = pathArray[ pathArray.length - 1 ] ;
    +
    +	if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +
    +	var pointer = pave( object , pathArray ) ;
    +
    +	if ( typeof pointer[ key ] === 'number' ) { pointer[ key ] -- ; }
    +	else if ( ! pointer[ key ] || typeof pointer[ key ] !== 'object' ) { pointer[ key ] = -1 ; }
    +
    +	return value ;
    +} ;
    +
    +
    +
    +dotPath.concat = ( object , path , value ) => {
    +	if ( ! object || typeof object !== 'object' ) {
    +		// Throw?
    +		return undefined ;
    +	}
    +
    +	var pathArray = toPathArray( path ) ,
    +		key = pathArray[ pathArray.length - 1 ] ;
    +
    +	if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +
    +	var pointer = pave( object , pathArray ) ;
    +
    +	if ( ! pointer[ key ] ) { pointer[ key ] = value ; }
    +	else if ( Array.isArray( pointer[ key ] ) && Array.isArray( value ) ) {
    +		pointer[ key ] = pointer[ key ].concat( value ) ;
    +	}
    +	//else ? do nothing???
    +
    +	return value ;
    +} ;
    +
    +
    +
    +dotPath.insert = ( object , path , value ) => {
    +	if ( ! object || typeof object !== 'object' ) {
    +		// Throw?
    +		return undefined ;
    +	}
    +
    +	var pathArray = toPathArray( path ) ,
    +		key = pathArray[ pathArray.length - 1 ] ;
    +
    +	if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +
    +	var pointer = pave( object , pathArray ) ;
    +
    +	if ( ! pointer[ key ] ) { pointer[ key ] = value ; }
    +	else if ( Array.isArray( pointer[ key ] ) && Array.isArray( value ) ) {
    +		pointer[ key ] = value.concat( pointer[ key ] ) ;
    +	}
    +	//else ? do nothing???
    +
    +	return value ;
    +} ;
    +
    +
    +
    +dotPath.delete = ( object , path ) => {
    +	var pathArray = toPathArray( path ) ,
    +		key = pathArray[ pathArray.length - 1 ] ;
    +
    +	if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +
    +	var pointer = walk( object , pathArray , -1 ) ;
    +
    +	if ( ! pointer || typeof pointer !== 'object' ) { return false ; }
    +
    +	return delete pointer[ key ] ;
    +} ;
    +
    +
    +
    +dotPath.autoPush = ( object , path , value ) => {
    +	if ( ! object || typeof object !== 'object' ) {
    +		// Throw?
    +		return undefined ;
    +	}
    +
    +	var pathArray = toPathArray( path ) ,
    +		key = pathArray[ pathArray.length - 1 ] ;
    +
    +	if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +
    +	var pointer = pave( object , pathArray ) ;
    +
    +	if ( pointer[ key ] === undefined ) { pointer[ key ] = value ; }
    +	else if ( Array.isArray( pointer[ key ] ) ) { pointer[ key ].push( value ) ; }
    +	else { pointer[ key ] = [ pointer[ key ] , value ] ; }
    +
    +	return pointer[ key ] ;
    +} ;
    +
    +
    +
    +dotPath.append = ( object , path , value ) => {
    +	if ( ! object || typeof object !== 'object' ) {
    +		// Throw?
    +		return undefined ;
    +	}
    +
    +	var pathArray = toPathArray( path ) ,
    +		key = pathArray[ pathArray.length - 1 ] ;
    +
    +	if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +
    +	var pointer = pave( object , pathArray ) ;
    +
    +	if ( ! pointer[ key ] ) { pointer[ key ] = [ value ] ; }
    +	else if ( Array.isArray( pointer[ key ] ) ) { pointer[ key ].push( value ) ; }
    +	//else ? do nothing???
    +
    +	return pointer[ key ] ;
    +} ;
    +
    +
    +
    +dotPath.prepend = ( object , path , value ) => {
    +	if ( ! object || typeof object !== 'object' ) {
    +		// Throw?
    +		return undefined ;
    +	}
    +
    +	var pathArray = toPathArray( path ) ,
    +		key = pathArray[ pathArray.length - 1 ] ;
    +
    +	if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +
    +	var pointer = pave( object , pathArray ) ;
    +
    +	if ( ! pointer[ key ] ) { pointer[ key ] = [ value ] ; }
    +	else if ( Array.isArray( pointer[ key ] ) ) { pointer[ key ].unshift( value ) ; }
    +	//else ? do nothing???
    +
    +	return pointer[ key ] ;
    +} ;
    +
    +
    +},{}],4:[function(require,module,exports){
    +/*
    +	Tree Kit
    +
    +	Copyright (c) 2014 - 2021 Cédric Ronvel
     
     	The MIT License (MIT)
     
    @@ -455,11 +763,11 @@ function extendOne( runtime , options , target , source ) {
     }
     
     
    -},{}],4:[function(require,module,exports){
    +},{}],5:[function(require,module,exports){
     /*
     	Tree Kit
     
    -	Copyright (c) 2014 - 2019 Cédric Ronvel
    +	Copyright (c) 2014 - 2021 Cédric Ronvel
     
     	The MIT License (MIT)
     
    @@ -486,17 +794,19 @@ function extendOne( runtime , options , target , source ) {
     
     
     
    -var treePath = {} ;
    +const treePath = {} ;
     module.exports = treePath ;
     
     
     
    -treePath.op = function op( type , object , path , value ) {
    +const PROTO_POLLUTION_MESSAGE = 'This would pollute prototype' ;
    +
    +
    +
    +treePath.op = function( type , object , path , value ) {
     	var i , parts , last , pointer , key , isArray = false , pathArrayMode = false , isGenericSet , canBeEmpty = true ;
     
    -	if ( ! object || ( typeof object !== 'object' && typeof object !== 'function' ) ) {
    -		return ;
    -	}
    +	if ( ! object || typeof object !== 'object' ) { return ; }
     
     	if ( typeof path === 'string' ) {
     		// Split the path into parts
    @@ -544,17 +854,19 @@ treePath.op = function op( type , object , path , value ) {
     		if ( pathArrayMode ) {
     			if ( key === undefined ) {
     				key = parts[ i ] ;
    +				if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
     				continue ;
     			}
     
    -			if ( ! pointer[ key ] || ( typeof pointer[ key ] !== 'object' && typeof pointer[ key ] !== 'function' ) ) {
    +			if ( typeof pointer[ key ] === 'function' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +			if ( ! pointer[ key ] || typeof pointer[ key ] !== 'object' ) {
     				if ( ! isGenericSet ) { return undefined ; }
     				pointer[ key ] = {} ;
     			}
     
     			pointer = pointer[ key ] ;
     			key = parts[ i ] ;
    -
    +			if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
     			continue ;
     		}
     		else if ( parts[ i ] === '.' ) {
    @@ -569,7 +881,8 @@ treePath.op = function op( type , object , path , value ) {
     				key = '' ;
     			}
     
    -			if ( ! pointer[ key ] || ( typeof pointer[ key ] !== 'object' && typeof pointer[ key ] !== 'function' ) ) {
    +			if ( typeof pointer[ key ] === 'function' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +			if ( ! pointer[ key ] || typeof pointer[ key ] !== 'object' ) {
     				if ( ! isGenericSet ) { return undefined ; }
     				pointer[ key ] = {} ;
     			}
    @@ -589,6 +902,7 @@ treePath.op = function op( type , object , path , value ) {
     				continue ;
     			}
     
    +			if ( typeof pointer[ key ] === 'function' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
     			if ( ! pointer[ key ] || ! Array.isArray( pointer[ key ] ) ) {
     				if ( ! isGenericSet ) { return undefined ; }
     				pointer[ key ] = [] ;
    @@ -606,11 +920,15 @@ treePath.op = function op( type , object , path , value ) {
     
     		canBeEmpty = false ;
     
    -		if ( ! isArray ) { key = parts[ i ] ; continue ; }
    +		if ( ! isArray ) {
    +			key = parts[ i ] ;
    +			if ( key === '__proto__' ) { throw new Error( PROTO_POLLUTION_MESSAGE ) ; }
    +			continue ;
    +		}
     
     		switch ( parts[ i ] ) {
     			case 'length' :
    -				key = parts[ i ] ;
    +				key = 'length' ;
     				break ;
     
     			// Pseudo-key
    @@ -727,7 +1045,7 @@ treePath.prototype = {
     
     
     // Upgrade an object so it can support get, set and delete at its root
    -treePath.upgrade = function upgrade( object ) {
    +treePath.upgrade = function( object ) {
     	Object.defineProperties( object , {
     		get: { value: treePath.op.bind( undefined , 'get' , object ) } ,
     		delete: { value: treePath.op.bind( undefined , 'delete' , object ) } ,
    
  • browser/tree-kit.min.js+1 1 modified
    @@ -1 +1 @@
    -(function(e){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=e()}else if(typeof define==="function"&&define.amd){define([],e)}else{var t;if(typeof window!=="undefined"){t=window}else if(typeof global!=="undefined"){t=global}else if(typeof self!=="undefined"){t=self}else{t=this}t.treeKit=e()}})(function(){var e,t,n;return function(){function e(t,n,r){function i(o,u){if(!n[o]){if(!t[o]){var s="function"==typeof require&&require;if(!u&&s)return s(o,!0);if(f)return f(o,!0);var a=new Error("Cannot find module '"+o+"'");throw a.code="MODULE_NOT_FOUND",a}var c=n[o]={exports:{}};t[o][0].call(c.exports,function(e){var n=t[o][1][e];return i(n||e)},c,c.exports,e,t,n,r)}return n[o].exports}for(var f="function"==typeof require&&require,o=0;o<r.length;o++)i(r[o]);return i}return e}()({1:[function(e,t,n){"use strict";var r={};t.exports=r;r.extend=e("./extend.js");r.clone=e("./clone.js");r.path=e("./path.js")},{"./clone.js":2,"./extend.js":3,"./path.js":4}],2:[function(e,t,n){"use strict";function r(e,t){var n=Object.getPrototypeOf(e);if(r.opaque.has(n)){return r.opaque.get(n)(e)}var i,f,o,u,s,a,c=[{source:e,target:Array.isArray(e)?[]:Object.create(n)}],p=c[0].target,d=new Map;d.set(e,p);while(u=c.shift()){o=Object.getOwnPropertyNames(u.source);for(i=0;i<o.length;i++){f=Object.getOwnPropertyDescriptor(u.source,o[i]);if(!f.value||typeof f.value!=="object"){Object.defineProperty(u.target,o[i],f);continue}s=f.value;if(t){if(d.has(s)){f.value=d.get(s);Object.defineProperty(u.target,o[i],f);continue}}a=Object.getPrototypeOf(f.value);if(r.opaque.has(a)){f.value=r.opaque.get(a)(f.value);Object.defineProperty(u.target,o[i],f);continue}f.value=Array.isArray(s)?[]:Object.create(a);if(t){d.set(s,f.value)}Object.defineProperty(u.target,o[i],f);c.push({source:s,target:f.value})}}return p}t.exports=r;r.opaque=new Map;r.opaque.set(Date.prototype,e=>new Date(e))},{}],3:[function(e,t,n){"use strict";function r(e,t,...n){var r,f,o=false,u=n.length;if(!u){return t}if(!e||typeof e!=="object"){e={}}var s={depth:0,prefix:""};if(e.deep){if(Array.isArray(e.deep)){e.deep=new Set(e.deep)}else if(!(e.deep instanceof Set)){e.deep=true}}if(e.immutables){if(Array.isArray(e.immutables)){e.immutables=new Set(e.immutables)}else if(!(e.immutables instanceof Set)){delete e.immutables}}if(!e.maxDepth&&e.deep&&!e.circular){e.maxDepth=100}if(e.deepFunc){e.deep=true}if(e.flat){e.deep=true;e.proto=false;e.inherit=false;e.unflat=false;if(typeof e.flat!=="string"){e.flat="."}}if(e.unflat){e.deep=false;e.proto=false;e.inherit=false;e.flat=false;if(typeof e.unflat!=="string"){e.unflat="."}}if(e.inherit){e.own=true;e.proto=false}else if(e.proto){e.own=true}if(!t||typeof t!=="object"&&typeof t!=="function"){o=true}if(!e.skipRoot&&(e.inherit||e.proto)){for(r=u-1;r>=0;r--){f=n[r];if(f&&(typeof f==="object"||typeof f==="function")){if(e.inherit){if(o){t=Object.create(f)}else{Object.setPrototypeOf(t,f)}}else if(e.proto){if(o){t=Object.create(Object.getPrototypeOf(f))}else{Object.setPrototypeOf(t,Object.getPrototypeOf(f))}}break}}}else if(o){t={}}s.references={sources:[],targets:[]};for(r=0;r<u;r++){f=n[r];if(!f||typeof f!=="object"&&typeof f!=="function"){continue}i(s,e,t,f)}return t}t.exports=r;function i(e,t,n,r){var f,o,u,s,a,c,p,d,l,b,y,h=-1;if(t.maxDepth&&e.depth>t.maxDepth){throw new Error("[tree] extend(): max depth reached("+t.maxDepth+")")}if(t.circular){e.references.sources.push(r);e.references.targets.push(n)}if(t.own){if(t.nonEnum){u=Object.getOwnPropertyNames(r)}else{u=Object.keys(r)}}else{u=r}for(s in u){if(t.own){s=u[s]}if(s==="__proto__"){continue}if(t.descriptor){d=Object.getOwnPropertyDescriptor(r,s);a=d.value}else{a=r[s]}b=n;l=e.prefix+s;if(t.nofunc&&typeof a==="function"){continue}if(t.unflat&&e.depth===0){y=s.split(t.unflat);o=y.length-1;if(o){for(f=0;f<o;f++){if(!b[y[f]]||typeof b[y[f]]!=="object"&&typeof b[y[f]]!=="function"){b[y[f]]={}}b=b[y[f]]}l=e.prefix+y[o]}}if(t.deep&&a&&(typeof a==="object"||t.deepFunc&&typeof a==="function")&&(!t.descriptor||!d.get)&&((c=Object.getPrototypeOf(a))||true)&&(!(t.deep instanceof Set)||t.deep.has(c))&&(!t.immutables||!t.immutables.has(c))){if(t.circular){h=e.references.sources.indexOf(a)}if(t.flat){if(h>=0){continue}i({depth:e.depth+1,prefix:e.prefix+s+t.flat,references:e.references},t,b,a)}else{if(h>=0){if(t.descriptor){Object.defineProperty(b,l,{value:e.references.targets[h],enumerable:d.enumerable,writable:d.writable,configurable:d.configurable})}else{b[l]=e.references.targets[h]}continue}if(!b[l]||!Object.prototype.hasOwnProperty.call(b,l)||typeof b[l]!=="object"&&typeof b[l]!=="function"){if(Array.isArray(a)){p=[]}else if(t.proto){p=Object.create(c)}else if(t.inherit){p=Object.create(a)}else{p={}}if(t.descriptor){Object.defineProperty(b,l,{value:p,enumerable:d.enumerable,writable:d.writable,configurable:d.configurable})}else{b[l]=p}}else if(t.proto&&Object.getPrototypeOf(b[l])!==c){Object.setPrototypeOf(b[l],c)}else if(t.inherit&&Object.getPrototypeOf(b[l])!==a){Object.setPrototypeOf(b[l],a)}if(t.circular){e.references.sources.push(a);e.references.targets.push(b[l])}i({depth:e.depth+1,prefix:"",references:e.references},t,b[l],a)}}else if(t.preserve&&b[l]!==undefined){continue}else if(!t.inherit){if(t.descriptor){Object.defineProperty(b,l,d)}else{b[l]=a}}if(t.move){delete r[s]}}}},{}],4:[function(e,t,n){"use strict";var r={};t.exports=r;r.op=function e(t,n,r,i){var f,o,u,s,a,c=false,p=false,d,l=true;if(!n||typeof n!=="object"&&typeof n!=="function"){return}if(typeof r==="string"){if(r){o=r.match(/([.#[\]]|[^.#[\]]+)/g)}else{o=[""]}if(o[0]==="."){o.unshift("")}if(o[o.length-1]==="."){o.push("")}}else if(Array.isArray(r)){o=r;p=true}else{throw new TypeError("[tree.path] ."+t+"(): the path argument should be a string or an array")}switch(t){case"get":case"delete":d=false;break;case"set":case"define":case"inc":case"dec":case"append":case"prepend":case"concat":case"insert":case"autoPush":d=true;break;default:throw new TypeError("[tree.path] .op(): wrong type of operation '"+t+"'")}s=n;u=o.length-1;for(f=0;f<=u;f++){if(p){if(a===undefined){a=o[f];continue}if(!s[a]||typeof s[a]!=="object"&&typeof s[a]!=="function"){if(!d){return undefined}s[a]={}}s=s[a];a=o[f];continue}else if(o[f]==="."){c=false;if(a===undefined){if(!l){l=true;continue}a=""}if(!s[a]||typeof s[a]!=="object"&&typeof s[a]!=="function"){if(!d){return undefined}s[a]={}}s=s[a];l=true;continue}else if(o[f]==="#"||o[f]==="["){c=true;l=false;if(a===undefined){if(!Array.isArray(s)){return undefined}continue}if(!s[a]||!Array.isArray(s[a])){if(!d){return undefined}s[a]=[]}s=s[a];continue}else if(o[f]==="]"){l=false;continue}l=false;if(!c){a=o[f];continue}switch(o[f]){case"length":a=o[f];break;case"first":a=0;break;case"last":a=s.length-1;if(a<0){a=0}break;case"next":if(!d){return undefined}a=s.length;break;case"insert":if(!d){return undefined}s.unshift(undefined);a=0;break;default:a=parseInt(o[f],10)}}switch(t){case"get":return s[a];case"delete":if(c&&typeof a==="number"){s.splice(a,1)}else{delete s[a]}return;case"set":s[a]=i;return s[a];case"define":if(!(a in s)){s[a]=i}return s[a];case"inc":if(typeof s[a]==="number"){s[a]++}else if(!s[a]||typeof s[a]!=="object"){s[a]=1}return s[a];case"dec":if(typeof s[a]==="number"){s[a]--}else if(!s[a]||typeof s[a]!=="object"){s[a]=-1}return s[a];case"append":if(!s[a]){s[a]=[i]}else if(Array.isArray(s[a])){s[a].push(i)}return s[a];case"prepend":if(!s[a]){s[a]=[i]}else if(Array.isArray(s[a])){s[a].unshift(i)}return s[a];case"concat":if(!s[a]){s[a]=i}else if(Array.isArray(s[a])&&Array.isArray(i)){s[a]=s[a].concat(i)}return s[a];case"insert":if(!s[a]){s[a]=i}else if(Array.isArray(s[a])&&Array.isArray(i)){s[a]=i.concat(s[a])}return s[a];case"autoPush":if(s[a]===undefined){s[a]=i}else if(Array.isArray(s[a])){s[a].push(i)}else{s[a]=[s[a],i]}return s[a]}};r.get=r.op.bind(undefined,"get");r.delete=r.op.bind(undefined,"delete");r.set=r.op.bind(undefined,"set");r.define=r.op.bind(undefined,"define");r.inc=r.op.bind(undefined,"inc");r.dec=r.op.bind(undefined,"dec");r.append=r.op.bind(undefined,"append");r.prepend=r.op.bind(undefined,"prepend");r.concat=r.op.bind(undefined,"concat");r.insert=r.op.bind(undefined,"insert");r.autoPush=r.op.bind(undefined,"autoPush");r.prototype={get:function(e){return r.get(this,e)},delete:function(e){return r.delete(this,e)},set:function(e,t){return r.set(this,e,t)},define:function(e,t){return r.define(this,e,t)},inc:function(e,t){return r.inc(this,e,t)},dec:function(e,t){return r.dec(this,e,t)},append:function(e,t){return r.append(this,e,t)},prepend:function(e,t){return r.prepend(this,e,t)},concat:function(e,t){return r.concat(this,e,t)},insert:function(e,t){return r.insert(this,e,t)},autoPush:function(e,t){return r.autoPush(this,e,t)}};r.upgrade=function e(t){Object.defineProperties(t,{get:{value:r.op.bind(undefined,"get",t)},delete:{value:r.op.bind(undefined,"delete",t)},set:{value:r.op.bind(undefined,"set",t)},define:{value:r.op.bind(undefined,"define",t)},inc:{value:r.op.bind(undefined,"inc",t)},dec:{value:r.op.bind(undefined,"dec",t)},append:{value:r.op.bind(undefined,"append",t)},prepend:{value:r.op.bind(undefined,"prepend",t)},concat:{value:r.op.bind(undefined,"concat",t)},insert:{value:r.op.bind(undefined,"insert",t)},autoPush:{value:r.op.bind(undefined,"autoPush",t)}})}},{}]},{},[1])(1)});
    \ No newline at end of file
    +(function(e){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=e()}else if(typeof define==="function"&&define.amd){define([],e)}else{var t;if(typeof window!=="undefined"){t=window}else if(typeof global!=="undefined"){t=global}else if(typeof self!=="undefined"){t=self}else{t=this}t.treeKit=e()}})(function(){var e,t,r;return function(){function e(t,r,n){function i(f,u){if(!r[f]){if(!t[f]){var a="function"==typeof require&&require;if(!u&&a)return a(f,!0);if(o)return o(f,!0);var s=new Error("Cannot find module '"+f+"'");throw s.code="MODULE_NOT_FOUND",s}var c=r[f]={exports:{}};t[f][0].call(c.exports,function(e){var r=t[f][1][e];return i(r||e)},c,c.exports,e,t,r,n)}return r[f].exports}for(var o="function"==typeof require&&require,f=0;f<n.length;f++)i(n[f]);return i}return e}()({1:[function(e,t,r){"use strict";const n={};t.exports=n;n.extend=e("./extend.js");n.clone=e("./clone.js");n.path=e("./path.js");n.dotPath=e("./dotPath.js")},{"./clone.js":2,"./dotPath.js":3,"./extend.js":4,"./path.js":5}],2:[function(e,t,r){"use strict";function n(e,t){var r=Object.getPrototypeOf(e);if(n.opaque.has(r)){return n.opaque.get(r)(e)}var i,o,f,u,a,s,c=[{source:e,target:Array.isArray(e)?[]:Object.create(r)}],p=c[0].target,d=new Map;d.set(e,p);while(u=c.shift()){f=Object.getOwnPropertyNames(u.source);for(i=0;i<f.length;i++){o=Object.getOwnPropertyDescriptor(u.source,f[i]);if(!o.value||typeof o.value!=="object"){Object.defineProperty(u.target,f[i],o);continue}a=o.value;if(t){if(d.has(a)){o.value=d.get(a);Object.defineProperty(u.target,f[i],o);continue}}s=Object.getPrototypeOf(o.value);if(n.opaque.has(s)){o.value=n.opaque.get(s)(o.value);Object.defineProperty(u.target,f[i],o);continue}o.value=Array.isArray(a)?[]:Object.create(s);if(t){d.set(a,o.value)}Object.defineProperty(u.target,f[i],o);c.push({source:a,target:o.value})}}return p}t.exports=n;n.opaque=new Map;n.opaque.set(Date.prototype,e=>new Date(e))},{}],3:[function(e,t,r){"use strict";const n={};t.exports=n;const i=[];const o="This would pollute prototype";function f(e){if(Array.isArray(e)){return e}else if(!e){return i}else if(typeof e==="string"){return e.split(".")}throw new TypeError("[tree.dotPath]: the path argument should be a string or an array")}function u(e,t,r=0){var n,i,f,u=e;for(n=0,i=t.length+r;n<i;n++){f=t[n];if(f==="__proto__"||typeof u==="function"){throw new Error(o)}if(!u||typeof u!=="object"){return undefined}u=u[f]}return u}function a(e,t){var r,n,i,f=e;for(r=0,n=t.length-1;r<n;r++){i=t[r];if(i==="__proto__"||typeof f[i]==="function"){throw new Error(o)}if(!f[i]||typeof f[i]!=="object"){f[i]={}}f=f[i]}return f}n.get=((e,t)=>u(e,f(t)));n.set=((e,t,r)=>{if(!e||typeof e!=="object"){return undefined}var n=f(t),i=n[n.length-1];if(i==="__proto__"){throw new Error(o)}var u=a(e,n);u[i]=r;return r});n.define=((e,t,r)=>{if(!e||typeof e!=="object"){return undefined}var n=f(t),i=n[n.length-1];if(i==="__proto__"){throw new Error(o)}var u=a(e,n);if(!(i in u)){u[i]=r}return r});n.inc=((e,t,r)=>{if(!e||typeof e!=="object"){return undefined}var n=f(t),i=n[n.length-1];if(i==="__proto__"){throw new Error(o)}var u=a(e,n);if(typeof u[i]==="number"){u[i]++}else if(!u[i]||typeof u[i]!=="object"){u[i]=1}return r});n.dec=((e,t,r)=>{if(!e||typeof e!=="object"){return undefined}var n=f(t),i=n[n.length-1];if(i==="__proto__"){throw new Error(o)}var u=a(e,n);if(typeof u[i]==="number"){u[i]--}else if(!u[i]||typeof u[i]!=="object"){u[i]=-1}return r});n.concat=((e,t,r)=>{if(!e||typeof e!=="object"){return undefined}var n=f(t),i=n[n.length-1];if(i==="__proto__"){throw new Error(o)}var u=a(e,n);if(!u[i]){u[i]=r}else if(Array.isArray(u[i])&&Array.isArray(r)){u[i]=u[i].concat(r)}return r});n.insert=((e,t,r)=>{if(!e||typeof e!=="object"){return undefined}var n=f(t),i=n[n.length-1];if(i==="__proto__"){throw new Error(o)}var u=a(e,n);if(!u[i]){u[i]=r}else if(Array.isArray(u[i])&&Array.isArray(r)){u[i]=r.concat(u[i])}return r});n.delete=((e,t)=>{var r=f(t),n=r[r.length-1];if(n==="__proto__"){throw new Error(o)}var i=u(e,r,-1);if(!i||typeof i!=="object"){return false}return delete i[n]});n.autoPush=((e,t,r)=>{if(!e||typeof e!=="object"){return undefined}var n=f(t),i=n[n.length-1];if(i==="__proto__"){throw new Error(o)}var u=a(e,n);if(u[i]===undefined){u[i]=r}else if(Array.isArray(u[i])){u[i].push(r)}else{u[i]=[u[i],r]}return u[i]});n.append=((e,t,r)=>{if(!e||typeof e!=="object"){return undefined}var n=f(t),i=n[n.length-1];if(i==="__proto__"){throw new Error(o)}var u=a(e,n);if(!u[i]){u[i]=[r]}else if(Array.isArray(u[i])){u[i].push(r)}return u[i]});n.prepend=((e,t,r)=>{if(!e||typeof e!=="object"){return undefined}var n=f(t),i=n[n.length-1];if(i==="__proto__"){throw new Error(o)}var u=a(e,n);if(!u[i]){u[i]=[r]}else if(Array.isArray(u[i])){u[i].unshift(r)}return u[i]})},{}],4:[function(e,t,r){"use strict";function n(e,t,...r){var n,o,f=false,u=r.length;if(!u){return t}if(!e||typeof e!=="object"){e={}}var a={depth:0,prefix:""};if(e.deep){if(Array.isArray(e.deep)){e.deep=new Set(e.deep)}else if(!(e.deep instanceof Set)){e.deep=true}}if(e.immutables){if(Array.isArray(e.immutables)){e.immutables=new Set(e.immutables)}else if(!(e.immutables instanceof Set)){delete e.immutables}}if(!e.maxDepth&&e.deep&&!e.circular){e.maxDepth=100}if(e.deepFunc){e.deep=true}if(e.flat){e.deep=true;e.proto=false;e.inherit=false;e.unflat=false;if(typeof e.flat!=="string"){e.flat="."}}if(e.unflat){e.deep=false;e.proto=false;e.inherit=false;e.flat=false;if(typeof e.unflat!=="string"){e.unflat="."}}if(e.inherit){e.own=true;e.proto=false}else if(e.proto){e.own=true}if(!t||typeof t!=="object"&&typeof t!=="function"){f=true}if(!e.skipRoot&&(e.inherit||e.proto)){for(n=u-1;n>=0;n--){o=r[n];if(o&&(typeof o==="object"||typeof o==="function")){if(e.inherit){if(f){t=Object.create(o)}else{Object.setPrototypeOf(t,o)}}else if(e.proto){if(f){t=Object.create(Object.getPrototypeOf(o))}else{Object.setPrototypeOf(t,Object.getPrototypeOf(o))}}break}}}else if(f){t={}}a.references={sources:[],targets:[]};for(n=0;n<u;n++){o=r[n];if(!o||typeof o!=="object"&&typeof o!=="function"){continue}i(a,e,t,o)}return t}t.exports=n;function i(e,t,r,n){var o,f,u,a,s,c,p,d,l,y,h,b=-1;if(t.maxDepth&&e.depth>t.maxDepth){throw new Error("[tree] extend(): max depth reached("+t.maxDepth+")")}if(t.circular){e.references.sources.push(n);e.references.targets.push(r)}if(t.own){if(t.nonEnum){u=Object.getOwnPropertyNames(n)}else{u=Object.keys(n)}}else{u=n}for(a in u){if(t.own){a=u[a]}if(a==="__proto__"){continue}if(t.descriptor){d=Object.getOwnPropertyDescriptor(n,a);s=d.value}else{s=n[a]}y=r;l=e.prefix+a;if(t.nofunc&&typeof s==="function"){continue}if(t.unflat&&e.depth===0){h=a.split(t.unflat);f=h.length-1;if(f){for(o=0;o<f;o++){if(!y[h[o]]||typeof y[h[o]]!=="object"&&typeof y[h[o]]!=="function"){y[h[o]]={}}y=y[h[o]]}l=e.prefix+h[f]}}if(t.deep&&s&&(typeof s==="object"||t.deepFunc&&typeof s==="function")&&(!t.descriptor||!d.get)&&((c=Object.getPrototypeOf(s))||true)&&(!(t.deep instanceof Set)||t.deep.has(c))&&(!t.immutables||!t.immutables.has(c))){if(t.circular){b=e.references.sources.indexOf(s)}if(t.flat){if(b>=0){continue}i({depth:e.depth+1,prefix:e.prefix+a+t.flat,references:e.references},t,y,s)}else{if(b>=0){if(t.descriptor){Object.defineProperty(y,l,{value:e.references.targets[b],enumerable:d.enumerable,writable:d.writable,configurable:d.configurable})}else{y[l]=e.references.targets[b]}continue}if(!y[l]||!Object.prototype.hasOwnProperty.call(y,l)||typeof y[l]!=="object"&&typeof y[l]!=="function"){if(Array.isArray(s)){p=[]}else if(t.proto){p=Object.create(c)}else if(t.inherit){p=Object.create(s)}else{p={}}if(t.descriptor){Object.defineProperty(y,l,{value:p,enumerable:d.enumerable,writable:d.writable,configurable:d.configurable})}else{y[l]=p}}else if(t.proto&&Object.getPrototypeOf(y[l])!==c){Object.setPrototypeOf(y[l],c)}else if(t.inherit&&Object.getPrototypeOf(y[l])!==s){Object.setPrototypeOf(y[l],s)}if(t.circular){e.references.sources.push(s);e.references.targets.push(y[l])}i({depth:e.depth+1,prefix:"",references:e.references},t,y[l],s)}}else if(t.preserve&&y[l]!==undefined){continue}else if(!t.inherit){if(t.descriptor){Object.defineProperty(y,l,d)}else{y[l]=s}}if(t.move){delete n[a]}}}},{}],5:[function(e,t,r){"use strict";const n={};t.exports=n;const i="This would pollute prototype";n.op=function(e,t,r,n){var o,f,u,a,s,c=false,p=false,d,l=true;if(!t||typeof t!=="object"){return}if(typeof r==="string"){if(r){f=r.match(/([.#[\]]|[^.#[\]]+)/g)}else{f=[""]}if(f[0]==="."){f.unshift("")}if(f[f.length-1]==="."){f.push("")}}else if(Array.isArray(r)){f=r;p=true}else{throw new TypeError("[tree.path] ."+e+"(): the path argument should be a string or an array")}switch(e){case"get":case"delete":d=false;break;case"set":case"define":case"inc":case"dec":case"append":case"prepend":case"concat":case"insert":case"autoPush":d=true;break;default:throw new TypeError("[tree.path] .op(): wrong type of operation '"+e+"'")}a=t;u=f.length-1;for(o=0;o<=u;o++){if(p){if(s===undefined){s=f[o];if(s==="__proto__"){throw new Error(i)}continue}if(typeof a[s]==="function"){throw new Error(i)}if(!a[s]||typeof a[s]!=="object"){if(!d){return undefined}a[s]={}}a=a[s];s=f[o];if(s==="__proto__"){throw new Error(i)}continue}else if(f[o]==="."){c=false;if(s===undefined){if(!l){l=true;continue}s=""}if(typeof a[s]==="function"){throw new Error(i)}if(!a[s]||typeof a[s]!=="object"){if(!d){return undefined}a[s]={}}a=a[s];l=true;continue}else if(f[o]==="#"||f[o]==="["){c=true;l=false;if(s===undefined){if(!Array.isArray(a)){return undefined}continue}if(typeof a[s]==="function"){throw new Error(i)}if(!a[s]||!Array.isArray(a[s])){if(!d){return undefined}a[s]=[]}a=a[s];continue}else if(f[o]==="]"){l=false;continue}l=false;if(!c){s=f[o];if(s==="__proto__"){throw new Error(i)}continue}switch(f[o]){case"length":s="length";break;case"first":s=0;break;case"last":s=a.length-1;if(s<0){s=0}break;case"next":if(!d){return undefined}s=a.length;break;case"insert":if(!d){return undefined}a.unshift(undefined);s=0;break;default:s=parseInt(f[o],10)}}switch(e){case"get":return a[s];case"delete":if(c&&typeof s==="number"){a.splice(s,1)}else{delete a[s]}return;case"set":a[s]=n;return a[s];case"define":if(!(s in a)){a[s]=n}return a[s];case"inc":if(typeof a[s]==="number"){a[s]++}else if(!a[s]||typeof a[s]!=="object"){a[s]=1}return a[s];case"dec":if(typeof a[s]==="number"){a[s]--}else if(!a[s]||typeof a[s]!=="object"){a[s]=-1}return a[s];case"append":if(!a[s]){a[s]=[n]}else if(Array.isArray(a[s])){a[s].push(n)}return a[s];case"prepend":if(!a[s]){a[s]=[n]}else if(Array.isArray(a[s])){a[s].unshift(n)}return a[s];case"concat":if(!a[s]){a[s]=n}else if(Array.isArray(a[s])&&Array.isArray(n)){a[s]=a[s].concat(n)}return a[s];case"insert":if(!a[s]){a[s]=n}else if(Array.isArray(a[s])&&Array.isArray(n)){a[s]=n.concat(a[s])}return a[s];case"autoPush":if(a[s]===undefined){a[s]=n}else if(Array.isArray(a[s])){a[s].push(n)}else{a[s]=[a[s],n]}return a[s]}};n.get=n.op.bind(undefined,"get");n.delete=n.op.bind(undefined,"delete");n.set=n.op.bind(undefined,"set");n.define=n.op.bind(undefined,"define");n.inc=n.op.bind(undefined,"inc");n.dec=n.op.bind(undefined,"dec");n.append=n.op.bind(undefined,"append");n.prepend=n.op.bind(undefined,"prepend");n.concat=n.op.bind(undefined,"concat");n.insert=n.op.bind(undefined,"insert");n.autoPush=n.op.bind(undefined,"autoPush");n.prototype={get:function(e){return n.get(this,e)},delete:function(e){return n.delete(this,e)},set:function(e,t){return n.set(this,e,t)},define:function(e,t){return n.define(this,e,t)},inc:function(e,t){return n.inc(this,e,t)},dec:function(e,t){return n.dec(this,e,t)},append:function(e,t){return n.append(this,e,t)},prepend:function(e,t){return n.prepend(this,e,t)},concat:function(e,t){return n.concat(this,e,t)},insert:function(e,t){return n.insert(this,e,t)},autoPush:function(e,t){return n.autoPush(this,e,t)}};n.upgrade=function(e){Object.defineProperties(e,{get:{value:n.op.bind(undefined,"get",e)},delete:{value:n.op.bind(undefined,"delete",e)},set:{value:n.op.bind(undefined,"set",e)},define:{value:n.op.bind(undefined,"define",e)},inc:{value:n.op.bind(undefined,"inc",e)},dec:{value:n.op.bind(undefined,"dec",e)},append:{value:n.op.bind(undefined,"append",e)},prepend:{value:n.op.bind(undefined,"prepend",e)},concat:{value:n.op.bind(undefined,"concat",e)},insert:{value:n.op.bind(undefined,"insert",e)},autoPush:{value:n.op.bind(undefined,"autoPush",e)}})}},{}]},{},[1])(1)});
    \ No newline at end of file
    
  • CHANGELOG+6 0 modified
    @@ -1,4 +1,10 @@
     
    +v0.7.0
    +------
    +
    +BREAKING CHANGE -- .path()/.dotPath(): drop the function's subtree support, fix prototype pollution
    +
    +
     v0.6.2
     ------
     
    
  • package.json+1 1 modified
    @@ -1,6 +1,6 @@
     {
       "name": "tree-kit",
    -  "version": "0.6.2",
    +  "version": "0.7.0",
       "description": "Tree utilities which provides a full-featured extend and object-cloning facility, and various tools to deal with nested object structures.",
       "main": "lib/tree.js",
       "directories": {
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.