From 6a1e3ef74f6eb345bcff1b82184201d1e28b6756 Mon Sep 17 00:00:00 2001 From: "David I. Lehn" Date: Tue, 1 Sep 2020 21:37:39 -0400 Subject: [PATCH] Remove object path functions. - Remove `util.getPath`, `util.setPath`, and `util.deletePath`. - These are unused in `forge` itself. - Path processing has potential security issues. (For `setPath` in particular). - `lodash` has better replacements: `get`, `set`, and `unset`. - See also: - CHANGELOG.md 0.9.2 entry. - https://snyk.io/vuln/SNYK-JS-NODEFORGE-598677 - https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7720 --- CHANGELOG.md | 15 ++++++-- README.md | 2 -- lib/util.js | 96 ---------------------------------------------------- 3 files changed, 13 insertions(+), 100 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10cc588a0..e3f1bfc5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,21 @@ Forge ChangeLog =============== +### Changed - **BREAKING**: Node.js 4 no longer supported. The code *may* still work, and non-invasive patches to keep it working will be considered. However, more - modern tools no longer support very old Node.js versions making testing - difficult. + modern tools no longer support old Node.js versions making testing difficult. + +### Removed +- **BREAKING**: Remove `util.getPath`, `util.setPath`, and `util.deletePath`. + `util.setPath` had a potential prototype pollution security issue when used + with unsafe inputs. These functions are not used by `forge` itself. They date + from an early time when `forge` was targeted at providing general helper + functions. The library direction changed to be more focused on cryptography. + Many other excellent libraries are more suitable for general utilities. If + you need a replacement for these functions, consier `get`, `set`, and `unset` + from [lodash](https://lodash.com/). But also consider the potential similar + security issues with those APIs. ## 0.9.2 - 2019-09-01 diff --git a/README.md b/README.md index ae7fc3cbe..40bf29561 100644 --- a/README.md +++ b/README.md @@ -2035,8 +2035,6 @@ When using this code please keep the following in mind: - Certain features in this library are less susceptible to attacks depending on usage. This primarily includes features that deal with data format manipulation or those that are not involved in communication. -- Do not pass unsafe inputs to `util.setPath`. Doing so could expose a - prototype pollution security issue. Library Background ------------------ diff --git a/lib/util.js b/lib/util.js index a6ad158f3..98dfd3427 100644 --- a/lib/util.js +++ b/lib/util.js @@ -2513,102 +2513,6 @@ util.makeLink = function(path, query, fragment) { ((fragment.length > 0) ? ('#' + fragment) : ''); }; -/** - * Follows a path of keys deep into an object hierarchy and set a value. - * If a key does not exist or it's value is not an object, create an - * object in it's place. This can be destructive to a object tree if - * leaf nodes are given as non-final path keys. - * Used to avoid exceptions from missing parts of the path. - * - * SECURITY NOTE: Do not use unsafe inputs. Doing so could expose a prototype - * pollution security issue. - * - * @param object the starting object. - * @param keys an array of string keys. - * @param value the value to set. - */ -util.setPath = function(object, keys, value) { - // need to start at an object - if(typeof(object) === 'object' && object !== null) { - var i = 0; - var len = keys.length; - while(i < len) { - var next = keys[i++]; - if(i == len) { - // last - object[next] = value; - } else { - // more - var hasNext = (next in object); - if(!hasNext || - (hasNext && typeof(object[next]) !== 'object') || - (hasNext && object[next] === null)) { - object[next] = {}; - } - object = object[next]; - } - } - } -}; - -/** - * Follows a path of keys deep into an object hierarchy and return a value. - * If a key does not exist, create an object in it's place. - * Used to avoid exceptions from missing parts of the path. - * - * @param object the starting object. - * @param keys an array of string keys. - * @param _default value to return if path not found. - * - * @return the value at the path if found, else default if given, else - * undefined. - */ -util.getPath = function(object, keys, _default) { - var i = 0; - var len = keys.length; - var hasNext = true; - while(hasNext && i < len && - typeof(object) === 'object' && object !== null) { - var next = keys[i++]; - hasNext = next in object; - if(hasNext) { - object = object[next]; - } - } - return (hasNext ? object : _default); -}; - -/** - * Follow a path of keys deep into an object hierarchy and delete the - * last one. If a key does not exist, do nothing. - * Used to avoid exceptions from missing parts of the path. - * - * @param object the starting object. - * @param keys an array of string keys. - */ -util.deletePath = function(object, keys) { - // need to start at an object - if(typeof(object) === 'object' && object !== null) { - var i = 0; - var len = keys.length; - while(i < len) { - var next = keys[i++]; - if(i == len) { - // last - delete object[next]; - } else { - // more - if(!(next in object) || - (typeof(object[next]) !== 'object') || - (object[next] === null)) { - break; - } - object = object[next]; - } - } - } -}; - /** * Check if an object is empty. *